数据库事务备忘录之三

      今天想写一些关于事务并发问题,当初在学习DB2的时候,就一直想弄明白,可是当时是为了应试,老师也没有讲得太明白,所以一直决心要总结一下,后来呢,就一直拖到了今天...闲话少讲了,开始正题吧!
      在并发的环境之中,一个数据库系统会同时为各种各样的客户端提供服务,对于同时运行的多个事务,当这些事务访问数据库中相同的数据时如果没有采取必要的隔离机制,就会出现各种并发问题,可以把这些问题归纳为一下五种:
       ----- 第一类丢失更新:撤销一个事务时,把其他事务已提交的更新数据覆盖。
       ----- 脏读:一个事务读到了另一个事务未提交的更新数据。
       ----- 虚读:一个事务读到了另一个事务已经提交的新插入的数据。
       ----- 不可重复读:一个事务读到另一个事务已提交的更新数据。
       ----- 第二类丢失更新:一个事务覆盖另一个事务已提交的更新数据,这时不可重复读的一个特例。
      这样的定义实在太过死板,而且让人也很难理解,还是通过一个例子来仔细的分析一下每一种并发问题,以下引用孙卫琴老师的《精通Hibernate:JAVA对象持久化技术详解》里面的例子,个人认为这个例子很不错。
      假设现在一所银行有一个取款事务和一个支票转账事务操作同一个银行账户的情形,首先我们假设两个事务顺序执行,而不是并发执行,那麽整个的步骤如下:
      ----- 银行客户在银行前台请求取款100元,出纳员先查询账户信息,得知存款余额为1000元。
      ----- 出纳员判断存款余额大于取款额,支付给客户100元,并将账户上的存款余额改为900元。
      ----- 出纳员处理一张转账支票,该支票向此账户汇入100元,出纳员先查询账户信息,得知存款余额为900元。
      ----- 出纳员将存款余额改为1000元。
      可以很清楚的看到,如果顺序的执行这两个事务,不会出现任何问题,可是现实之中并非如此简单,如果两个事务分别由两个出纳员同时执行那麽可能就会出现并发的问题,下面我们分别来介绍:
  
1.第一类丢失更新
           
              时 间     取款事务                                         转账事务
            -------------------------------------------------------------------------------------------------
               T1         开始事务
               T2                                                                   开始事务
               T3         查询账户余额为1000元                              
               T4                                                                   查询账户余额为1000元
               T5                                                                   汇入100元,把余额改为1100元
               T6                                                                   提交事务
               T7         取出100元,把余额改为900元
               T8         撤销事务,余额恢复为1000元
            --------------------------------------------------------------------------------------------------
      如果按照以上的时间次序并发执行的话,由于支票转账事务对存款余额所做的更新被取款事务的撤销所覆盖,所以客户会损失100元。
 

2.脏 读
           
             时 间      取款事务                                    转账事务
            ---------------------------------------------------------------------------------------------------
               T1         开始事务
               T2                                                                  开始事务
               T3         查询账户余额为1000元                              
               T4                                 
               T5         取出100元,把余额改为900元                            
               T6                                                                  查询账户余额为900元(脏读)
               T7        撤销事务,余额恢复为1000元
               T8                                                                  汇入100元,把余额改为1000元
               T9                                                                  提交事务
            --------------------------------------------------------------------------------------------------
      由于支票转账事务查询了取款事务未提交的更新数据,并且在这个查询结果的基础上进行了更新操作,如果取款事务最后被撤销 ,会导致银行客户损失100元。
 

3.虚 读
      下面我们另举一个例子来看看什么是虚读。
            时 间      注册事务                                   统计事务
            -----------------------------------------------------------------------------------------
               T1        开始事务
               T2                                                            开始事务
               T3                                                            统计注册客户总数为10000人                             
               T4        注册一个新用户                           
               T5        提交事务                         
               T6                                                            统计注册客户总数为10001人
               T7                                                            到底哪一个统计数据有效?
            -----------------------------------------------------------------------------------------
      统计事务无法相信查询的结果,因为查询结果是不确定的,随时可能被其他事务改变。     
      对于实际应用,在一个事务中不会对相同的数据查询两次,假定统计事务在T3时刻统计注册客户的总数,执行SELECT语句,在T6时刻不再查询数据库,而是直接打印统计结果为10000,这个统计结果与数据库当中数据是有所出入的,确切的说,它反映的是T3时刻的数据状态,而不是当前的数据状态。应该根据实际需要来决定是否允许虚读。以上面的统计事务为例,如果仅仅想大致了解一下注册客户总数,那麽可以允许虚读;如果在一个事务中,会依据查询结果来做出精确的决策,那麽就必须采取必要的事务隔离措施,避免虚读。

 4.不可重复读

             时 间      取款事务                                              转账事务
            -----------------------------------------------------------------------------------------------------
               T1        开始事务
               T2                                                                       开始事务
               T3        查询账户余额为1000元                                                           
               T4                                                                       查询账户余额为1000元
               T5        取出100元,把余额改为900元                            
               T6        提交事务                          
               T7                                                                       查询账户余额为900元
               T8                                                                       余额到底是1000元还是900元?
            ----------------------------------------------------------------------------------------------------- 
      如上面所示,如果支票转账事务两次查询账户的存款余额,但得到了不同的查询结果,这使得银行出纳员无法相信查询结果,因为查询结果是不确定的,随时可能被其他事务改变。
 

5.第二类丢失更新
           
             时 间     取款事务                                            转账事务
            ----------------------------------------------------------------------------------------------------
               T1       开始事务
               T2                                                                     开始事务
               T3       查询账户余额为1000元                              
               T4                                                                    查询账户余额为1000元
               T5       取出100元,把余额改为900元                            
               T6       提交事务                          
               T7    
               T8                                                                     汇入100元,把余额改为1100元
               T9                                                                     提交事务
            ----------------------------------------------------------------------------------------------------
      每个事务都不知道其他事务的存在,最后一个事务对记录所做的更新将覆盖由其他事务对记录所做的已提交的更新。上面的例子里由于支票转账事务覆盖了取款事务对存款余额所做的更新,导致银行最后损失了100元,哈哈,你是不是开始喜欢第二类丢失更新了呢?
      怎样才能消除这些并发问题呢?请听下回......

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值