我理解的事务隔离级别, 就是在并发情况下, 能够包装一个事务内的数据, 不会被其他并发执行的事务影响。 但是这些隔离级别,还是无法解决并发下的一些问题。 
比如用户A转账给用户B,用户C也转账给用户B
过程为:A所在的事务                                          C 所在的事务
1、查询出B的余额为100                     1、查询出B的余额为100
2、100 + 10(转账金额)                   2、100 + 10(转账金额)
3、修改B用户的金额为110                  3、修改B用户的金额为110这样还是会丢失掉其中一个事务的更新要解决这样问题的话, 还是要用锁, 即,在查询出B的余额的时候,使用for update查询语句。
那么问题来了。 
应该是我对事务隔离级别的理解还不够, 想请问一下, 事务隔离主要的作用是什么?  应用场景是什么?   能解决什么样的问题呢?

解决方案 »

  1.   

    建议做个测试,应该不会丢。 或者检查一下当前的事务隔离级别及表的存储引擎类型。
    如果AA所在的事务  先执行,在执行中 C 所在的事务 启动, 查询出B的余额为100 会试图加R锁,而此此刻如果设置的事务隔离正确,则会导致C事务等待A事务的解锁。\
    关于MYSQL支持的四种隔离级别,可以参考一下MYSQL的官方免费手册或者百度一下。
    READ UNCOMMITTED
    READ COMMITTED
    REPEATABLE READ
    SERIALIZABLE
      

  2.   

    使用的是Innodb存储引擎
    做过测试。 
    不管使用READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ中的哪种隔离级别。
    在并发时都会导致丢失掉其中一个事务的更新比如表 T(user ,  money)
    主键是user第一个事务中                                                                                              第二个事务中
    start transaction ;                                                                                       start transaction ;     
    1、select money from T where user =  B ;                                           1、select money from T where user = B ;
    查询出money = 100                                                                                   查询出money = 100
    2、然后 money = 100 + 10 (转10块钱给用户B)                              2、然后money =100 + 10(转10块钱给用户B)
    3、update T set money = ?(110) where user = B ;                             3、update T set money = ?(110) where user = B ;
    commit ;                                                                                                       commit ;如果第一个事务和第二个事务中的三步都是同时进行的, 那么最后数据库中的结果就是110
    因为第一步 select money from T where user = B 没有给数据加任何锁, 除非将语句改成 select money from T where user = B for update ,这样的话, 两个事务就串行处理了。 所以我不明白事务的隔离级别的应用场景是什么?  能达到什么目的呢?
      

  3.   

    使用的是Innodb存储引擎
    做过测试。 
    不管使用READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ中的哪种隔离级别。
    在并发时都会导致丢失掉其中一个事务的更新比如表 T(user ,  money)
    主键是user第一个事务中                                                                                              第二个事务中
    start transaction ;                                                                                       start transaction ;     
    1、select money from T where user =  B ;                                           1、select money from T where user = B ;
    查询出money = 100                                                                                   查询出money = 100
    2、然后 money = 100 + 10 (转10块钱给用户B)                              2、然后money =100 + 10(转10块钱给用户B)
    3、update T set money = ?(110) where user = B ;                             3、update T set money = ?(110) where user = B ;
    commit ;                                                                                                       commit ;如果第一个事务和第二个事务中的三步都是同时进行的, 那么最后数据库中的结果就是110
    因为第一步 select money from T where user = B 没有给数据加任何锁, 除非将语句改成 select money from T where user = B for update ,这样的话, 两个事务就串行处理了。 所以我不明白事务的隔离级别的应用场景是什么?  能达到什么目的呢?

    第一个事务中                                                                                              第二个事务中
    start transaction ;                                                                                       start transaction ;     
    1、select money from T where user =  B ;                                           1、select money from T where user = B ;
    查询出money = 100                                                                                   查询出money = 100
    2、然后 money = 100 + 10 (转10块钱给用户B)                              2、然后money =100 + 10(转10块钱给用户B)
    3、update T set money = ?(110) where user = B ;                             3、update T set money = ?(110) where user = B ;
    commit ;                                                                                                       commit ;
      

  4.   


    第一个事务中                                                                                              第二个事务中
    start transaction ;                                                                                       start transaction ;     
    1、select money from T where user =  B ;                                           1、select money from T where user = B ;
    查询出money = 100                                                                                   查询出money = 100
    2、然后 money = 100 + 10 (转10块钱给用户B)                              2、然后money =100 + 10(转10块钱给用户B)
    3、update T set money = ?(110) where user = B ;                             3、update T set money = ?(110) where user = B ;
    commit ;                                                                                                       commit ;