有两个进程同时修改一条数据,每次加一,但有个问题,如果同时取到那个数据,就会造成一个进程的修改丢失。比如数据为5,进程1,2同时加1,结果应该为7,现在 结果为6.
    框架采用SSM,在service层的处理:        @Transactional(propagation = Propagation.REQUIRES_NEW)
public String getSerialNumber() {
               //查询数据
List<DocSeq> docSeqs = docSeqMapper.selectDocSeq(docSeq);
               //处理过后更新
updateDocSeq(docSeqs.get(0), request);
} mybatis中的查询     <select id="selectDocSeq" >
 SELECT *
  FROM 表名
  WHERE 条件
  FOR UPDATE
    </select>    这样处理后并不能实现表加锁,两个进程还是会同时修改相同的值,有木有大神知道该如何去处理这个问题?

解决方案 »

  1.   

    --写一条语句用锁控制一下
    update tt set nn=nn+1 where id=1;
      

  2.   

    具体呢?for update锁吗?在xml中写了,并不能锁住那条数据,当你在plsql中把数据锁了之后就不能更新了,但是程序中写了for update 并不能锁表数据??
      

  3.   

    不要用 for update .直接 按 1# 的方法就可以了;
      

  4.   


    语句在执行的时候才会加锁。
    你用select for update道理是一样的,执行到selectDocSeq 这个id的时候才会加锁
      

  5.   


    语句在执行的时候才会加锁。
    你用select for update道理是一样的,执行到selectDocSeq 这个id的时候才会加锁在处理的地方加断点或者睡眠,另开一个网页去操作数据还是会取到值,按理说在select后那条数据就加锁了,另一个网页不应该取到值得啊?这是我最疑惑的地方?是spring事务有问题吗?如果在plsql中把那条数据锁了,再用网页去操作的时候就会等在查询那,也取不到值。
      

  6.   


    语句在执行的时候才会加锁。
    你用select for update道理是一样的,执行到selectDocSeq 这个id的时候才会加锁在处理的地方加断点或者睡眠,另开一个网页去操作数据还是会取到值,按理说在select后那条数据就加锁了,另一个网页不应该取到值得啊?这是我最疑惑的地方?是spring事务有问题吗?如果在plsql中把那条数据锁了,再用网页去操作的时候就会等在查询那,也取不到值。锁数据只是不让修改,并不影响查询。可以取到数据
      

  7.   

    和加锁没关系,关键是业务上,当其它进程修改记录后是否允许直接累加更新而不需要取新数据进行判断。
    一、允许累加
    两个进程各自用增量去更新(就是#1的方式),而不是用自己增加后的结果(6)直接去覆盖数据库字段。
    二、不允许累加
    在条件中加上更新前的值,再取一下更新记录数(sql%rowcount),为0则表示其它进程已经修改了数据,向用户报错。
    update tt set nn=6 where id=1 and nn=5;