Spring 在高层次建立了统一的事务抽象以及一致的编程模板 。
Spring 提供了事务模板类 TransactionTemplate。 通过 TransactionTemplate 并配合使用事务回调 TransactionCallback 来指定具体的持久化操作,从而通过编程的方式来实现事务管理。
通过声明,在 IoC 配置中指定事务的边界和事务属性, Spring 就会自动在指定的事务边界上应用事务属性 。
因为大部分的应用都是单数据源的,只有少部分需要使用多数据源的 JTA 事务。所以在单数据源的场景中,Spring 使用底层数据源来管理事务。如果遇到多数据源的场景,Spring 会引用应用服务器中的 JNDI 资源来实现 JTA 事务。在 Spring 中,不管我们是否使用了 JTA 事务,事务的管理模型都是相同的。
1 事务管理模型
Spring 事务管理 SPI ( Service Provider Interface )抽象模型层主要包括 3 个接口:
- PlatformTransactionManager
- TransactionDefinition
- TransactionStatus
TransactionDefinition 定义了事务隔离级别、超时时间、是否只读以及事务传播规则等事务属性。PlatformTransactionManager 依据 TransactionDefinition 中的配置信息来创建事务。而 TransactionStatus 描述了事务的当前状态。
2 TransactionDefinition
TransactionDefinition 定义了与事务管理控制相关的配置信息。
1、事务隔离级别:
在此,定义了与 java.sql.Connection 相同的四种隔离级别。此外,还定义了默认隔离级别(ISOLATION_DEFAULT ),它会使用底层数据库所定义的默认隔离级别。
2、事务传播机制:
3、事务超时设置:
int TIMEOUT_DEFAULT = -1;
复制代码
事务执行超过时限设置,即超时后,回滚事务。
4、只读状态:
boolean isReadOnly();
复制代码
设置为只读状态之后,可以提供执行性能。如果试图修改只读事务中的事务,将抛出异常。
3 TransactionStatus
TransactionStatus 代表的是某个事务的运行状态。事务管理器就是通过它,来获取事务的运行状态。因为继承了 SavepointManager 接口,所以也可以回滚事务。
SavepointManager 接口有这些方法:
方法 | 说明 |
---|---|
Object createSavepoint() |
创建保存点。 |
void rollbackToSavepoint(Object savepoint) |
将事务回滚到特定保存点。 |
void releaseSavepoint(Object savepoint) |
事务提交后,释放保存点。 |
注意: 如果底层事务不支持 “保存点”,那么将抛出 NestedTransactionNotSupportedException。
TransactionStatus 中,除了继承了 SavepointManager 接口方法之外,还定义了以下方法:
方法 | 说明 |
---|---|
boolean hasSavepoint() |
判断当前事务内部是否创建了保存点,它用于嵌套事务的情况。 |
boolean isNewTransaction() |
判断当前事务是否是新事务。如果返回 false,则表示当前事务是一个已存在的事务,或者当前操作未运行在事务环境。 |
boolean isCompleted() |
判断当前事务是否已结束。 |
boolean isRollbackOnly() |
判断当前事务是否被标注为 “rollback-only”。 |
void setRollbackOnly() |
将当前事务标注为 “rollback-only”。标注之后,事务管理器将显式调用回滚命令或抛出异常等方式来回滚当前事务。 |
4 PlatformTransactionManager
PlatformTransactionManager 定义了三个方法,它们都没有绑定 JNDI。
方法 | 说明 |
---|---|
TransactionStatus getTransaction(TransactionDefinition definition) |
从当前事务环境中,获取一个已存在的事务,或者创建一个新事务,实际返回的是事务的状态。 |
void commit(TransactionStatus status) |
依据事务状态,来提交事务。如果事务被标注为 “rollback-only”,则回滚事务。 |
void rollback(TransactionStatus status) |
回滚事务。如果 commit() 方法抛出异常,那么 Spring 会隐式调用 rollback() 。 |