事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功。
我们先举一个例子来描述一下事务:
假设要张三通过银行给李四进行转账1000元钱,张三原有余额10000元整,李四有人民币3000元整。
以下是操作流程:
时间 t1 检查张三余额是否够转账
时间 t2 从张三中扣除1000元
时间t3 在李四的账户中添加1000元
在上述的步骤的操作必须打包在一个事务-转账,我们可把它描述为这个事务程序:
t0 开始事务
t1 SELECT balance FROM account_tab WHERE account_name='张三'' ;
t2 UPDATE account_tab SET balance=balance-1000 WHERE account_name='张三'' ;
t3 UPDATE account_tab SET balance=balance+1000 WHERE account_name='李四'' ;
t4 COMMIT;
我们假设在t3李四的账户中添加1000元发生失败,则这次转账业务失败,我们需要数据回滚到最初始状态。
将扣除的1000元钱回滚给张三的账户,否则后果不堪设想。
要满足事务开发中的准确性,那么在数据库事务程序不可不理解事务的四大特性【ACID】
- 原子性(atomicity)
一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对一个事务来说,不可能
只执行其中的一部分操作,这是事务的原子性。
- 一致性(consistency)
数据库总数从一个一致性的状态转换到另外一个一致性状态。以转账为例,如果在t3出现错误,事务没有提交,所欲事务做的修改就不会保存到数据库。确保了数据的一致性。
- 隔离性(isolation)
通常说,一个事务所做的修改在最终提交前,对其它事务不可见的。它由一些隔离机制来控制。
- 持久性(durability)
一旦事务提交,则其所做的修改就会永久保存到数据库中。此时即使系统奔溃,修改的数据也不会丢失。
在四大特性中影响我们开发的主要以隔离性为主,接下来我们看看数据库的隔离性:
脏读(读取未提交数据)READ UNCOMMITED
在事务的修改即使没有提交也是对其它事务可见的。事务可以读取未提交的数据。这个级别的事务隔离会导致很多问题。
B事务读取A事务尚未提交的数据,此时如果A事务发生错误并执行回滚操作,那么A事务读取到的数据就是脏数据。举例如下
不可重复读
两次读取的内容不一致
幻读
当某个事务在读取某个范围内的记录时另外一个事务对该范围内插入了新的记录。
“不可重复读“和“幻读”的区别
- 不可重复读是读取了其他事务更改的数据
- 幻读是读取了其他事务新增的数据