Spring 事务原理

一、事务管理器

概述:
Spring 提供了事务管理器的接口,具体实现由 ORM 框架提供

PlatformTransactionManager:事务管理器核⼼接⼝。提供标准

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public interface PlatformTransactionManager { 
/**
* 获取事务状态信息
*/
TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;

/**
* 提交事务
*/
void commit(TransactionStatus status) throws TransactionException;

/**
* 回滚事务
*/
void rollback(TransactionStatus status) throws TransactionException;
}

二、事务属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public interface TransactionDefinition {
// 返回事务的传播行为
int getPropagationBehavior();
// 返回事务的隔离级别,事务管理器根据它来控制另外一个事务可以看到本事务内的哪些数据
int getIsolationLevel();
//返回事务的名字
String getName();
// 返回事务超时时间
int getTimeout();
// 返回是否优化为只读事务
boolean isReadOnly();

// 隔离级别、传播行为
...
}

1. 事务隔离级别

  • ISOLATION_DEFAULT: 使用后端数据库默认的隔离级别

    Mysql 默认采用的 REPEATABLE_READ 隔离级别
    Oracle 默认采用的 READ_COMMITTED 隔离级别

  • ISOLATION_READ_UNCOMMITTED: 未提交读,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读

  • ISOLATION_READ_COMMITTED: 已提交读,允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生

  • ISOLATION_REPEATABLE_READ: 可重复读,对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生

  • ISOLATION_SERIALIZABLE: 可串行化,所有的事务依次逐个执行, _可以防止脏读、不可重复读以及幻读。_但是这将严重影响程序的性能。通常情况下也不会用到该级别

2. 事务传播行为

概述:当事务方法被另一个事务方法调用时,必须指定事务应该如何传播

  • 支持当前事务:
    • PROPAGATION_REQUIRED: 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务
    • PROPAGATION_SUPPORTS: 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行
    • PROPAGATION_MANDATORY: 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常
  • 不支持当前事务:
    • PROPAGATION_REQUIRES_NEW: 如果当前存在事务,则把当前事务挂起;如果当前没有事务,则创建一个新的事务
    • PROPAGATION_NOT_SUPPORTED: 如果当前存在事务,则把当前事务挂起;如果当前没有事务,则以非事务方式运行
    • PROPAGATION_NEVER:如果当前存在事务,则抛出异常;如果当前没有事务,则以非事务方式运行
  • 其他情况:
    • PROPAGATION_NESTED: 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于 PROPAGATION_REQUIRED