你讨论的是事务并发的问题
对于这种问题,为了保持数据的一致性一般都是先用select ... for update no wait 来加行占锁,其他的sesssion只能等到最先用户事务提交之后才能更新,这样就保证了数据一致性

解决方案 »

  1.   

    楼上还是没明白我的意思。
    事务A在执行的过程中,事务B是可以进行Select操作的,那么B计算出来的结果和A计算出来的结果还是一致的。我现在就是想在事务A执行的时候,事务B不能执行,只有等A执行完后,才可以,也就是说Select也不可以执行。
      

  2.   

    FYI:
    http://www.akadia.com/services/ora_locks_survival_guide.html
      

  3.   

    Exclusive Table Locks (X)An exclusive table lock is the most restrictive mode of table lock, allowing the transaction that holds the lock exclusive write access to the table. An exclusive table lock is acquired for a table as follows:LOCK TABLE table IN EXCLUSIVE MODE;Permitted Operations:Only one transaction can obtain an exclusive table lock for a table. An exclusive table lock permits other transactions only to query the table.Prohibited Operations:An exclusive table lock held by a transaction prohibits other transactions from performing any type of DML statement or placing any type of lock on the table.---------------------------------
    An exclusive table lock permits other transactions only to query the table.所以,即使最严格的锁也无法禁止别的transaction访问(select)你的表,除非revoke select privilege,但是这种做法我个人觉得不是很好
      

  4.   

    按照你的方法假设有两个session: A,Bsession A:
    select ....for update wait 10//得到原有值
    ;;;;// 计算新的编号
    update ...// 更新表
    --commit;session B:
    select ....for update wait 10//得到原有值
    ;;;;// 计算新的编号
    update ...// 更新表
    --commit;假设A在B之前执行,且A未提交事务时B开始执行(即发生事务并发),这个时候因为select for update把目标表中符合条件select出来的row都给锁住了,B可以只读访问,但是无法更改被锁住的行,当B update的时候,B不得不等待,如果A 在B运行update10分钟之内提交的话,那么B的update语句就会被执行,否则到了10分钟之后A还没有提交B就强制失败,并且结束所有的操作,等于对数据库没有更新,只要A不结束事务,那么锁住的记录将会永远被锁住
      

  5.   

    kulama回答是正确的
    我后来也发现这个问题了,
    没仔细看这个问题,只要能确保锁同一条记录就可以了。
    揭帖