这篇文章主要介绍了Spring事务管理原理及方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
事务,在日常开发或者面试中都必定会涉及到。开发工作中,结合数据库开发理解就是:一组dml要么全部成功执行提交,要么因为某一个操作异常,撤销之前所做的成功的操作,整体执行失败。再简单点的一句话:生死与共。
由此,可以看出,事务的必要性:在开发工作中,保证操作数据的安全性。事务的控制也就是保证数据的访问安全性。
一、事务的四大特性
A:原子性(atomicity),对数据的修改,要么全部成功执行,要么全部不执行。
C:一致性(consistency),一旦事务完成,系统必须保证数据职员是满足业务状态的一种一致状态中。很难懂的解释,跟原子性很像。一个事务在操作过程中,数据可能会产生很多中间态,一致性保证中间态对其他事务不可见,因为这些中间态,与事务的开始和结束的状态是不一致的。也就是从一种正确的状态到另一种正确的状态。
I:隔离性(isolation),事务之间的执行应不相互影响,也即事务执行的独立。
D:持久性(durability),事务一旦提交,则对数据库的修改是永久性的。
二、事务的隔离级别
并发环境下,事务可能会存在若干问题:脏读、幻读、不可重复读、第一类更新丢失、第二类更新丢失。
类型 | 说明 | 举例 |
脏读 | A事务读取到了B事务未提交的数据 | A开启事务=>B开启事务,读取账户1000块,取走100块=>A读取账户金额,读取到900=>B回滚事务。此时A读取的余额数据是无效的 |
幻读 | 一个事务里面的操作发现了未被操作的数据 |
A开启事务,修改某些数据状态=>B开启事务,执行新增数据并提交=>A事务提交,会出现一条未被修改的数据。 幻读发生的前提是并发事务中发生了新增或者删除动作。 |
不可重复读 | 一个事务中,先后两次读取数据,读到的结果不一致 |
A开启事务,读取账户1000块=>B开启事务,读取账户1000块,取出100块并提交事务=>A再读取账户余额,余额900块。 一个事务范围内的两次同样的查询,却返回了两次不同的数据,这就是不可重复读 |
第一类更新丢失 | A事务撤销,把已经提交的B事务的更新的数据覆盖 | A开启事务,读取账户1000块=>B开启事务,读取账户1000块,然后增加100块,提交事务,账户变为1100=>A撤销回滚事务,账户成1000块 |
第二类更新丢失 | A事务提交,把已经提交的B事务的更新的数据覆盖 | A开启事务,读取账户1000块=>B开启事务,读取账户1000块,然后增加100块,提交事务,账户变为1100=>A增加100块,提交事务,账户变为1100。 |
针对并发环境下可能出现的事务问题,于是就出现了隔离级别的解决方案,由低到高依次是:读未提交(Read uncommitted)、读已提交(Read committed)、可重复读(Repeatable read)、串行序列化(serializable)。下表展示出不同的隔离级别,对于脏读、幻读、不可重复读是否会出现。