回顾Spring事务(概念)

1. 事务介绍

通俗的说,所谓事务就是操作一组数据库操作,要么都成功,要么都失败。

事务有四种特性(ACID):

  • 原子性(atomicity),强调事务是一个不可分割的整体,要么都执行成功,要么都执行失败;
  • 一致性(consistency),事务执行前后保证数据的完整性,比如A向B转账,不存在A扣了钱,B还未收到帐;
  • 隔离性(isolation),当事务操作某一数据时,不允许其他事务来干扰,比如A取钱的时候,不允许B给A转账;
  • 持久性(durability),事务一旦结束,数据就会持久到数据库中,也就是说,一旦提交(commit)后,是不可以回退(rollback)的。

2. 事务问题

那么使用事务的过程中会遇到哪些问题呢?

主要有三种:脏读、不可重复读和幻读。

2.1 脏读

定义:一个事务读取另一个发生失败和回滚的事务中未提交的数据;

举例:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据。

2.2 不可重复读

定义:一个事务在读某一行数据时,另一个事务也在更新这条数据,然后发现多次查询结果不一致;

举例:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。

2.3 幻读

定义:一个事务在读取多行数据时,另一个事务也在处理这些数据,然后发现多次查询返回的行数不一致;

举例:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。

3. 事务隔离

事务隔离便是解决多个事务之间的脏读、不可重复读和幻读问题。

事务隔离有四种:读未提交、读已提交、可重复读和序列化。

  • 读未提交(read-uncommitted):级别最低,脏读、不可重复读和幻读都有可能发生;
  • 读已提交(read-committed):可避免脏读,不可避免不可重复读和幻读;
  • 可重复读:可避免脏读和不可重复读,不可避免幻读;
  • 串行化:级别最高,表示都可避免;
事务隔离级别 脏读 不可重复读 幻读
读未提交(read-uncommitted)
读已提交(read-committed)
可重复读(repeatable-read)
串行化(serializable)

数据库事务隔离对比:

  • Oracle 只支持 读已提交(read-committed)和串行化(serializable),默认是读已提交;
  • MySQL 读未提交、读已提交、可重复读和序列化这四种都支持,默认可重复读(repeatable-read)。

在 Spring 中默认使用数据库的隔离级别。

4. 事务传播

在 Spring 中定义了有七种事务传播行为,用来处理一个事务方法被另一个事务方法调用时该如何进行。

事务传播行为类型 说明
PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

注意:

  • 事务传播行为针对的被调用的事务方法;
  • 上面所说的当前事务,是指的是外层方法(调用者);

文章作者: 叶遮沉阳
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 叶遮沉阳 !
  目录