事务概念

Author Avatar
xuanzh.cc 11月 01, 2017
  • 在其它设备中阅读本文章

事务特性

1、原子性(Atomic):

表示组成一个事务的多个数据库操作是一个不可分割的原子单元,只有所有的操作执行成功,整个事务才提交,事务中的任何一个数据库操作失败,则已经进行的操作都必须撤销让数据库返回到初始状态

2、一致性(Consistency):

事务操作成功后,数据库和它所处的状态必须是一致的,即数据不会被破坏

3、隔离性(Isolation):

在并发数据操作时,不同的事务拥有各自的数据空间,他们的操作不会对对方造成干扰。准确的说,并非要求做到完全无干扰,数据库规定了多种事务隔离级别不同级别对应的干扰程度不同,隔离界别越高,数据一致性也越好,但并发性也越弱。

4、持久性(Durabiliy):

一旦事务提交成功后,事务中的所有数据操作都必须被持久化到数据库中,即使事务提交后,数据库马上崩溃,再重启数据库时,也必须保证能够通过某种机制恢复数据。


数据并发问题

数据库中的相同数据被多个事务访问时,如果没有采取必要的隔离措施,就回导致各种并发问题,破坏数据的完整性。这些问题可以归纳为如下五类,包括三类数据读问题和两类数据更新问题:

三类数据读为题

1、 脏读(dirty read):

A事务读取B事务尚未提交的更改数据,并在这个数据基础上操作。恰巧B事务回滚,那么A事务读到的数据本身是不被承认的。例子如下

时间 A事务 B事务
T1 开始事务
T2 开始事务
T3 查询账户余额为1000元
T4 取出500,把账户余额更新为500元
T5 查询账户余额为500元(脏读)
T6 撤销事务,账户余额恢复为1000
T7 汇入100账户余额变为600元
T8 提交事务 .
2. 不可重复读(unrepeated read):

事务读取了B事务已经提交的更改数据

时间 A事务 B事务
T1 开始事务
T2 开始事务
T3 查询余额为1000元
T4 查询余额为1000元
T5 取出100将余额变为900元
T6 提交事务
T7 查询账户余额为900元(与T4读取的不一样) .
3. 幻象读(phantom read):

事务读取了B事务提交的新增数据,这时A事务将出现幻象读的问题。

时间 A事务 B事务
T1 开始事务
T2 开始事务
T3 统计总存款数为10000元
T4 新增账户,存款为100元
T5 提交事务
T6 统计总存款数为10100元(和T3统计的不一样) .

注意:幻象读和不可重复读是两个不同的概念,前者是指读到了其他事务已经提交的新增的数据,后者是指读到了其他事务已经提交的更新数据(修改或者删除)。
为了避免这两种情况,采用的对策是不一样的,防止读到更改数据,只需要对操作的数据添加行级锁,阻止操作中的数据变化;防止读到新增的数据,则往往需要添加表级锁,将整个表锁定,防止新增数据。

两类数据更新问题

1、 第一类丢失更新:

事务撤销时,吧已经提交的B事务的更新数据覆盖了。

时间 A事务 B事务
T1 开始事务
T2 开始事务
T3 查询账户余额为1000元
T4 查询账户余额为1000元
T5 存入100,将账户余额更新为1100
T6 提交事务
T7 取出100,将账户余额更新为900元
T8 撤销事务
T9 余额恢复为1000元(丢失更新) .
2、 第二类丢失更新:

事务覆盖B事务已经提交的数据,造成B事务所做的操作丢失。

时间 A事务 B事务
T1 开始事务
T2 开始事务
T3 查询账户余额为1000元
T4 查询账户余额为1000元
T5 存入100,将账户余额更新为1100
T6 提交事务
T7 存入100,将账户余额更新为1100元
T8 提交事务
T9 余额变为1100元(丢失更新) .

事务隔离级别

虽然数据库为我们提供了锁的DML操作方式,但是直接使用锁管理是比较麻烦的,所以数据库为我们提供了自动锁机制。只要我们(用户)指定事务隔离级别,数据库就回自动分析事务中的 SQL 语句,然后自动为事务操作的数据资源加上合适的锁,此外数据库还会维护这些锁,当一个资源上的锁数目太多时,自动进行锁升级以提高系统的运行性能。(这一过程对我们来说是透明的)

ANSI/ISO SQL 92 标准定义了四个等级的事务耿立级别,如下图:

隔离界别 脏读 不可重复读 幻象读 第一类更新丢失 第二类更新丢失
READ UNCOMMITED 允许 允许 允许 允许 允许
READ COMMITED 不允许 允许 允许 不允许 允许
REPEATABLE READ 不允许 不允许 允许 不允许 不允许
SERIALIZABLE 不允许 不允许 不允许 不允许 不允许

注意:事务的隔离级别和数据库的并发现是对立的,两种此增彼长。