很常见的问题
账户里有1000元
A查余额--1000
这时B存了500元,并完成提交
A再去存100元除了比较更新时间,还有别的好方法么?

解决方案 »

  1.   

    你可以在A操作时锁定这个账户,这样别人就不能更改这个账户了,当A提交完毕,释放这个锁,B才能再提交你业可以设置数据库隔离级别,数据库会按隔离级别自动进行锁定
    read uncommited : 读未提交数据(会出现脏读,不可重复读和幻读)
    read commited :读已提交数据(会出现不可重复读和幻读)
    repeatable read :可重复读(会出现幻读)
    serializable:串行化脏读:一个事务读取到另一事务未提交更新的数据。
    不可重复读:在同一事务中,多次读取同一数据返回的结果有所不同。换句话说就是,后续读取可以读到另一事务提交的更新数据。相反,“可重复读”在同一事务中多次读取数据时,能够保证所读数据一样,也就是,后续读取不能读到另一事务已提交的更新数据。
    幻读:一个事务读取到另一事务已提交的insert数据。
      

  2.   

    如果是汇款,怎么判断锁定账户?查询就锁?直到先用这个账户的人注销session?
      

  3.   

    用synchronized关键字,锁住就行,可以解决同步。
      

  4.   

    一个是同步代码块,synchronized(obj),括号里的obj就是对目标对象的锁定;
    另一个是同步方法,是用这个关键字来修饰某个方法,public synchronized void test();
      

  5.   

    怎么锁?A查询的时候就把账户锁定?禁止B存款?直到A退出?
      

  6.   

    从业务逻辑上来限制,一般银行系统都会限制一个帐户在不同的机器同一时间的同时LOGIN.从技术角度上来限制的话,synchronized这种方法是不可取的.synchronized只会限制在同一时间一个代码段不被同时使用.
    这个问题必须用DB的事务来处理,一个是设置DB的事务级别,还有就是要判断数据的时间戳.
      

  7.   


    为什么我做的项目都不用这些?  而且都是Oracle的数据库。
      

  8.   

    如果设为串行是不是就不用时间戳了?串行化的效率是不是很低?
    这方面没接触过,从来都是在Java程序里处理的
      

  9.   

    并发执行中会出现的一些数据不一致问题:
    1. 丢失修改(Lost Update)。是指两个事务T1和T2从数据库读取同一数据并进行修改,其中事务T2提交的修改结果破坏了事务T1提交的修改结果,导致了事务T1的修改被丢失。丢失修改是由于两个事务对同一数据并发地进行写入操作所引起的,因而称为写-写冲突(Write-Write Conflict)。
    2. 读"脏"数据(Dirty Read)。是指事务T1将数据a修改成数据b,然后将其写入磁盘;此后事务T2读取该修改后的数据,即数据b;接下来T1因故被撤销,使得数据b恢复到了原值a。这时,T2得到的数据就与数据库内的数据不一致。这种不一致或者不存在的数据通常就称为"脏"数据。
    3. 不可重复读(Non-repeatable Read)。是指当事务T1读取数据a后,事务T2进行读取并进行更新操作,使得T1再读取a进行校验时,发现前后两次读取值发生了变化,从而无法再读取前一次读取的结果。
    4. 幻象读(Phantom Read)。在事务T1前后两次相同的查询执行的时间间隔内,另一个事务T2对数据库执行了插入或删除操作,从而影响了T1查询的结果。隔离级别(Isolation Levels)是指一个事务与另一个事务之间隔离的程度,用于限制在并发条件下数据库交叉存储现象的发生。常见的隔离级别有:
    1. 未提交读(READ UNCOMMITED)。事务隔离的最低级别,仅可保证不读物理损坏的数据。
    2. 提交读(READ COMMITED)。SQL Server的默认级别,可以保证不读"脏"数据,但会发生不可重复读。
    3. 可重复读(REPEATABLE READ)。可以保证读一致性,防止不可重复读现象的发生,但会发生幻象读。
    4. 可串行化(SERIALIZABLE)。事务隔离的最高级别,事务之间完全隔离,在该级别上可以保证并发事务均是可串行的。在该隔离级别上不会发生幻象读。这些隔离级别按照隔离程度有小到大排序,隔离程度越大,隔离效果越好,可保证数据的正确性,但并发度小;隔离程度越小,隔离效果越差,越容易发生数据不一致现象,但并发度较大。
      

  10.   

    你的解决方法是利用乐观锁解决问题,其实乐观锁也可以使用版本控制,比如A操作时,数据表的版本是1,然后B也操作,版本也是1,之后A提交,那张修改的表的版本就变成了2,B在提交就过期了。
    当然也可以利用悲观锁,这种很影响性能(现实中用得少),只是一些金融领域对事务和数据一致性要求很高的项目中使用
      

  11.   

    线程问题
    可以用synchronized试试