参考:Spring事务实现原理 - insaneXs - 博客园 (cnblogs.com)
一、事务前置
JDBC原生事务管理
// 获取mysql数据库连接 Connection conn = DriverManager.getConnection("xxxx"); conn.setAutoCommit(false); statement = conn.createStatement(); // 执行sql,返回结果集 resultSet = statement.executeQuery("xxxx"); //提交 conn.commit(); //conn.rollback();//回滚
Spring则将这个过程进行了深度封装,最基础原理还是这个
Spring事务API
Spring提供了很多关于事务的API。但是最为基本的就是PlatformTransactionManager
、TransactionDefintion
和TransactionStatus
。
事务管理器——PlatformTransactionManager
PlatformTransactionManager
是事务管理器的顶层接口。事务的管理是受限于具体的数据源的(例如,JDBC对应的事务管理器就是DatasourceTransactionManager
),因此PlatformTransactionManager
只规定了事务的基本操作:创建事务,提交事物和回滚事务。
public interface PlatformTransactionManager extends TransactionManager { // 根据事务定义获取事务/开启事务 TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException; // 事务提交 void commit(TransactionStatus status) throws TransactionException; // 事务回滚 void rollback(TransactionStatus status) throws TransactionException; }
同时为了简化事务管理器的实现,Spring提供了一个抽象类AbstractPlatformTransactionManager
,规定了事务管理器的基本框架,仅将依赖于具体平台的特性作为抽象方法留给子类实现。
事务状态——TransactionStatus
事务状态是我对TransactionStatus
这个类的直译。其实我觉得这个类可以直接当作事务的超集来看(包含了事务对象,并且存储了事务的状态)。PlatformTransactionManager.getTransaction()
时创建的也正是这个对象。
这个对象的方法都和事务状态相关:
public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable { // 当前事务是否存在保存点 boolean hasSavepoint(); // 刷新数据, 和底层数据库是否支持有关, 略 @Override void flush(); }
可以看到 TransactionStatus 继承了 TransactionExecution 和 SavepointManager ,前者提供当前事务状态访问,后者提供保存点的访问
public interface TransactionExecution { // 是否是一个新事务, 是否在一个事务内部 boolean isNewTransaction(); // 触发回滚, 异常会回滚, 设置了这个标志位也会回滚 void setRollbackOnly(); boolean isRollbackOnly(); // 事务是否已结束, 已提交 || 已回滚 boolean isCompleted(); }
public interface SavepointManager { // 创建保存点 Object createSavepoint() throws TransactionException; // 回滚到保存点 void rollbackToSavepoint(Object savepoint) throws TransactionException; // 释放保存点 void releaseSavepoint(Object savepoint) throws TransactionException; }
事务属性的定义——TransactionDefinition
大致只需知道:传播行为 + 隔离级别
public interface TransactionDefinition { // 默认事务传播行为, 没有事务新建事务, 有事务在事务内执行 default int getPropagationBehavior() { return PROPAGATION_REQUIRED; } // 默认事务隔离级别 default int getIsolationLevel() { return ISOLATION_DEFAULT; } // 超时时间(-1) default int getTimeout() { return TIMEOUT_DEFAULT; } // 是否只读事务, 这个也是要看数据库是否支持 default boolean isReadOnly() { return false; } @Nullable default String getName() { return null; } // Static builder methods static TransactionDefinition withDefaults() { return StaticTransactionDefinition.INSTANCE; } }
编程式使用Spring事务
有了上述这些API,就已经可以通过编程的方式实现Spring的事务控制了。
但是Spring官方建议不要直接使用PlatformTransactionManager
这一偏低层的API来编程,而是使用TransactionTemplate
和TransactionCallback
这两个偏向用户层的接口。
示例代码如下:
//设置事务的各种属性;可以猜测TransactionTemplate应该是实现了TransactionDefinition transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); transactionTemplate.setTimeout(30000); //执行事务 将业务逻辑封装在TransactionCallback中 transactionTemplate.execute(new TransactionCallback<Object>() { @Override public Object doInTransaction(TransactionStatus transactionStatus) { //.... 业务代码 } });
以上就是Spring事务最基本的原理。但是为什么这些过程对我们似乎都不可见呢?那是因为这些过程都通过AOP的方式被织入了我们的业务逻辑中。
所以,像要深入了解Spring事务原理,还需要了解AOP的原理。
二、事务原理
AOP增强逻辑 TransactionInterceptor,实现了 MethodInterceptor由Spring AOP 原理可知内部就是增强逻辑
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {