数据库事务(二)

数据并发的问题 
    一个数据库可能拥有多个访问客户端,这些客户端都可以并发方式访问数据库。数据库中的相同数据可能同时被多个事务访问,如果没有采取必要的隔离措施,就会导致各种并发问题,破坏数据的完整性。这些问题可以归结为5类,包括3类数据读问题(脏读、幻象读和不可重复读)以及2类数据更新问题(第一类丢失更新和第二类丢失更新)。下面,我们分别通过实例讲解引发问题的场景。

脏读(dirty read) 
    在讲解脏读前,我们先讲一个笑话:一个有结巴的人在饮料店柜台前转悠,老板很热情地迎上来:“喝一瓶?”,结巴连忙说:“我…喝…喝…”,老板麻利地打开易拉罐递给结巴,结巴终于憋出了他的那句话:“我…喝…喝…喝不起啊!”。在这个笑话中,饮料店老板就对结巴进行了脏读。 
A事务读取B事务尚未提交的更改数据,并在这个数据的基础上操作。如果恰巧B事务回滚,那么A事务读到的数据根本是不被承认的。来看取款事务和转账事务并发时引发的脏读场景:


时间

转账事务A

取款事务B

T1

 

开始事务

T2

开始事务

 

T3

     

查询账户余额为1000元    

T4

        

取出500元把余额改为500元

T5

查询账户余额为500元(脏读)

 

T6

 

撤销事务余额恢复为1000元

T7

汇入100元把余额改为600元

 

T8

提交事务

 

  在这个场景中,B希望取款500元而后又撤销了动作,而A往相同的账户中转账100元,就因为A事务读取了B事务尚未提交的数据,因而造成账户白白丢失了500元。

不可重复读(unrepeatable read) 
   不可重复读是指A事务读取了B事务已经提交的更改数据。假设A在取款事务的过程中,B往该账户转账100元,A两次读取账户的余额发生不一致:


时间

取款事务A

转账事务B

T1

 

开始事务

T2

开始事务

                          

T3

                              

查询账户余额为1000元     

T4

查询账户余额为1000元

                          

T5

                  

取出100元把余额改为900元

T6

 

提交事务                  

T7

查询账户余额为900元(和T4读取的不一致)

 

  在同一事务中,T4时间点和T7时间点读取账户存款余额不一样。
幻象读(phantom read) 
    A事务读取B事务提交的新增数据,这时A事务将出现幻象读的问题。幻象读一般发生在计算统计数据的事务中,举一个例子,假设银行系统在同一个事务中,两次统计存款账户的总金额,在两次统计过程中,刚好新增了一个存款账户,并存入100元,这时,两次统计的总金额将不一致:


时间

统计金额事务A

转账事务B

T1

 

开始事务

T2

开始事务

             

T3

统计总存款数为10000元

             

T4

 

新增一个存款账户,存款为100元

T5

 

提交事务     

T6

再次统计总存款数为10100元(幻象读)

 

  如果新增数据刚好满足事务的查询条件,这个新数据就进入了事务的视野,因而产生了两个统计不一致的情况。 
  幻象读和不可重复读是两个容易混淆的概念,前者是指读到了其它已经提交事务的新增数据,而后者是指读到了已经提交事务的更改数据(更改或删除),为了避免这两种情况,采取的对策是不同的,防止读取到更改数据,只需要对操作的数据添加行级锁,阻止操作中的数据发生变化,而防止读取到新增数据,则往往需要添加表级锁——将整个表锁定,防止新增数据。

第一类丢失更新 
    A事务撤销时,把已经提交的B事务的更新数据覆盖了。这种错误可能造成很严重的问题,通过下面的账户取款转账就可以看出来:


时间

取款事务A

转账事务B

T1

开始事务

 

T2

 

开始事务

T3

查询账户余额为1000元    

 

T4

 

查询账户余额为1000元

T5

 

汇入100元把余额改为1100元

T6

 

提交事务

T7

取出100元把余额改为900元

 

T8

撤销事务

 

T9

余额恢复为1000元(丢失更新)

 

  A事务在撤销时,“不小心”将B事务已经转入账户的金额给抹去了。 
第二类丢失更新 
  A事务覆盖B事务已经提交的数据,造成B事务所做操作丢失:


时间

转账事务A

取款事务B

T1

 

开始事务

T2

开始事务

                         

T3

               

查询账户余额为1000元    

T4

查询账户余额为1000元

                         

T5

 

取出100元把余额改为900元

T6

 

提交事务           

T7

汇入100元

 

T8

提交事务

 

T9

把余额改为1100元(丢失更新)

 

上面的例子里由于支票转账事务覆盖了取款事务对存款余额所做的更新,导致银行最后损失了100元,相反如果转账事务先提交,那么用户账户将损失100元。

时间: 2024-07-28 17:46:09

数据库事务(二)的相关文章

[数据库事务与锁]详解二: 数据库的读现象浅析

注明: 本文转载自http://www.hollischuang.com/archives/900 “读现象”是多个事务并发执行时,在读取数据方面可能碰到的状况.先了解它们有助于理解各隔离级别的含义.其中包括脏读.不可重复读和幻读. 脏读 脏读又称无效数据的读出,是指在数据库访问中,事务T1将某一值修改,然后事务T2读取该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的. 脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交(commit)到

深入Spring数据库事务管理(二)

数据库的相关知识 1.数据库事务ACID特性 原子性(Atomicity): 说的是一个事物内所有操作共同组成一个原子包,要么全部成功,要么全部失败.这是最基本的特性,保证了因为一些其他因素导致数据库异常,或者宕机. 一致性(Consistency): 数据库事物的一致性就规定了事物提交前后,永远只可能存在事物提交前的状态和事物提交后的状态,从一个一致性的状态到另一个一致性状态,而不可能出现中间的过程态.也就是说事物的执行结果是量子化状态,而不是线性状态. 隔离性(Isolation): 事物的

[数据库事务与锁]详解三: 深入分析事务的隔离级别

注明: 本文转载自http://www.hollischuang.com/archives/943 本文详细介绍四种事务隔离级别,并通过举例的方式说明不同的级别能解决什么样的读现象.并且介绍了在关系型数据库中不同的隔离级别的实现原理. 在DBMS中,事务保证了一个操作序列可以全部都执行或者全部都不执行(原子性),从一个状态转变到另外一个状态(一致性).由于事务满足久性.所以一旦事务被提交之后,数据就能够被持久化下来,又因为事务是满足隔离性的,所以,当多个事务同时处理同一个数据的时候,多个事务直接

数据库事务解析

数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行. 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源.通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠.一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性.一致性.隔离性和持久性)属性.事务是数据库运行中的一个逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理. 1.操

我理解的数据库事务

一.最简单的例子来说明事务 "A账户向B账号汇钱"来说明事务 1.从A账号中把余额读出来.2.对A账号做减法操作.3.把结果写回A账号中.4.从B账号中把余额读出来.5.对B账号做加法操作.6.把结果写回B账号中. 为了数据的一致性,这6件事,要么都成功做完,要么都不成功.而且这个操作的过程中.对A.B找好的其他访问必须锁死,所谓锁死就是要排除其他的读写操作,不然会有脏数据问题,这就是事务. 二.数据库事务特性 Atomic(原子性) 事务中包含的操作被看做一个逻辑单元,这个逻辑单元中

数据库事务原理与实现

一.什么是数据库事务 数据库事务是指作为单个逻辑工作单元执行的一系列操作. 设想网上购物的一次交易,其付款过程至少包括以下几步数据库操作: · 更新客户所购商品的库存信息 · 保存客户付款信息--可能包括与银行系统的交互 · 生成订单并且保存到数据库中 · 更新用户相关信息,例如购物数量等等 正常的情况下,这些操作将顺利进行,最终交易成功,与交易相关的所有数据库信息也成功地更新.但是,如果在这一系列过程中任何一个环节出了差错,例如在更新商品库存信息时发生异常.该顾客银行帐户存款不足等,都将导致交

数据库事务之声明式事务

一.事务概述 1.在JavaEE企业级开发的应用领域,为了保证数据的完整性和一致性,必须引入数据库事务的概念,所以事务管理是企业级应用程序开发中必不可少的技术. 2.事务就是一组由于逻辑上紧密关联而合并成一个整体(工作单元)的多个数据库操作,这些操作要么都执行,要么都不执行. 3.事务的四个关键属性(ACID) 3.1.原子性(atomicity):"原子"的本意是"不可再分",事务的原子性表现为一个事务中涉及到的多个操作在逻辑上缺一不可.事务的原子性要求事务中的所

MYSQL数据库事务介绍

一.数据库事务介绍 简单地说,事务就是指逻辑上的一组SQL语句操作,组成这组操作的各个SQL语句, 执行时要么全成功要么全失败. 列如:小明给小红转账5块钱,流程如下: 1.从小明银行卡取出5元,计算式money-5 2.把上面5块钱打入小红的账号上,小红收到5块,money+5 上述转账的过程,对应的sql语句为: update  xiaoming_account set money=money-5 where name='xiaoming'; update  xiaohong_account

数据库事务隔离级别-- 脏读、幻读、不可重复读

一.数据库事务隔离级别 数据库事务的隔离级别有4个,由低到高依次为Read uncommitted .Read committed .Repeatable read .Serializable ,这四个级别可以逐个解决脏读 .不可重复读 .幻读 这几类问题. √: 可能出现    ×: 不会出现   脏读 不可重复读 幻读 Read uncommitted √ √ √ Read committed × √ √ Repeatable read × × √ Serializable × × × 注意

数据库:自己理解的“数据库事务隔离级别”

转载请注明出处: jiq?钦's technical Blog - 季义钦 引言:在网上搜了很多关于事务的文章,感觉单独来看都很难看懂,所以综合自己的理解写一篇我自己能理解的关于关系型数据库事务的文章. 一.事务特征 我们都知道数据库事务具备ACID特性: Atomic(原子性):一个事务要么成功,要么失败 Consistency(一致性):一致性代表了底层数据存储的完整性.事务执行前后数据库都必须处于一个合法的状态.什么才是一个合法的状态? 比如满足数据库的唯一性约束.数据类型验证.引用完整性