spring 事务管理
2021-10-14 17:38:48 7 举报
11
作者其他创作
大纲/内容
txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
status.createAndHoldSavepoint();
catch挂起时发生错误执行同步器resume()
TransactionAttributeSourcePointcut
TransactionSynchronizationManager.setActualTransactionActive(status.hasTransaction());
handleExistingTransaction(()
初始化事务信息
PROPAGATION_NEVER -- 以非事务方式执行,如果当前存在事务,则抛出异常。
读取设置隔离级别
for (RollbackRuleAttribute rule : this.rollbackRules) { int depth = rule.getDepth(ex); if (depth >= 0 && depth < deepest) { deepest = depth; winner = rule; } }读取全部规则并进行校验,这里的校验是递归校验
代理执行
PointCut
Object suspendedResources = suspend(transaction);
true 部分流程发生错误需要全局回滚
没有savepoint
事务是由当前方法创建的直接提交
List<TransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();
return super.rollbackOn(ex);
事务挂起
设置属性为TransactionAttributeSourcePointcut类型的PointCut
doRollback(status);
TransactionInterceptor interceptor = new TransactionInterceptor();\t\tinterceptor.setTransactionAttributeSource(transactionAttributeSource());\t\tif (this.txManager != null) {\t\t\tinterceptor.setTransactionManager(this.txManager);\t\t}\t\treturn interceptor;
commitTransactionAfterReturning(txInfo);
TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(\t\t\t\t\tdefinition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT ?\t\t\t\t\t\t\tdefinition.getIsolationLevel() : null);
finally
为匹配到是全部错误都会回滚
不存在连接
抛异常
cleanupAfterCompletion(status);
SuspendedResourcesHolder suspendedResources = suspend(transaction);
如果未匹配到调用父校验规则
PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
全局回滚自己没有发生异常但是在执行链路中其他方法发生异常需要进行全局回滚,配合局部异常全局回滚参数一起使用 isGlobalRollbackOnParticipationFailure 该参数默认为true 当设置为 false 时 标识将不再回滚,而不是说回滚部分在不借助savepoint的情况下是无法进行部分回滚的
status.releaseHeldSavepoint();
调用
如果存在savepoint 就进行销毁
回滚到savepoint
TransactionManagementConfigurationSelector是ImportSelector的实现类 可以进通过全限名的方式注册bean
doSetRollbackOnly(status);
retVal = invocation.proceedWithInvocation();
未匹配到规则,或者匹配到回归规则
TransactionSynchronizationManager.setCurrentTransactionName(definition.getName());
事务初始化
恢复
con = txObject.getConnectionHolder().getConnection();
提交 commit
false 不发新建事务 采取非非事务运行
测试连通性 通过后设置事务状态为true
调用新建一个事务
构架事务
doResumeSynchronization(suspendedSynchronizations);
PROPAGATION_NESTED -- 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
异常
实现AbstractPlatformTransactionManager.getTransaction()
String name = TransactionSynchronizationManager.getCurrentTransactionName(); TransactionSynchronizationManager.setCurrentTransactionName(null); boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly(); TransactionSynchronizationManager.setCurrentTransactionReadOnly(false); Integer isolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel(); TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(null); boolean wasActive = TransactionSynchronizationManager.isActualTransactionActive();
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() { @Override @Nullable protected TransactionAttributeSource getTransactionAttributeSource() { return transactionAttributeSource; } };
执行同步器
完成
创建事务
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY
(ex instanceof RuntimeException || ex instanceof Error);
事务管理入口
当前事务的隔离级别 记录
异常处理
匹配到规则 确认是 回滚规则还是不回滚规则
BeanFactoryTransactionAttributeSourceAdvisor是Advisor的实现类 在初始后将会对bean进行匹配 匹配完成后将会更新切面逻辑Advice构建动态代理对象 最终执行的将会是Advice的invoke方法所以在这个Advisor的核心逻辑便是PointCut和Advice
强制回滚 通过如下方式设置TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();在很多场景下当发生异常是 我们开发人员需要将这个错误返回前台,所以需要catch这个错误 封住自己的错误对象 。 这样spring 事务管理将无法感知到异常的发生,这是就需要我们用上面的方法 手动指定回滚
当存在已经挂起的资源
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED
构建事务挂起对象
PROPAGATION_REQUIRES_NEW -- 新建事务,如果当前存在事务,把当前事务挂起。
status.isNewTransaction()
调用将连接和事务对象制空
执行同步器方法
status.getSuspendedResources() != null
当前存在事务 抛出异常
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
事务提交调用
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());
ProxyTransactionManagementConfiguration
defStatus.isLocalRollbackOnly()
判断当前事务对象中是否存在连接
事务是当前方法创建的直接回滚
return
读取Transactional的属性
return !(winner instanceof NoRollbackRuleAttribute);
@Override\tpublic Pointcut getPointcut() {\t\treturn this.pointcut;\t}
doCommit(status);
实现selectImports 注册了2个bean
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||\t\t\t\tdefinition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||\t\t\t\tdefinition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED
返回结果
判断 全局回滚标志是否isGlobalRollbackOnParticipationFailure
这个方法中将会扫描类是否被@Transactional 或者存在方法被@Transactional 修饰 分别通过 ClassFilter实现
销毁事务 与 恢复
创建一个savepoint
记录当前事务名
设置当前存在事务的标志
获取事务状态
cleanupAfterCompletion(status);
无需回滚
triggerBeforeCompletion(status);
status.hasSavepoint()
执行
执行triggerBeforeCompletion();方法
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED
初始化同步器
status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()
2个bean中ProxyTransactionManagementConfiguration为核心功能
获取新建或者读取的数据库连接
NOT_SUPORTED
NEVER
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW
REQUIRES_NEW
else
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();\t\tadvisor.setTransactionAttributeSource(transactionAttributeSource());\t\tadvisor.setAdvice(transactionInterceptor());
是否存在savepoint 集传播放时为NESTED
status.rollbackToHeldSavepoint();
TransactionSynchronizationManager.initSynchronization();
prepareForCommit(status);\t\t\t\ttriggerBeforeCommit(status);\t\t\t\ttriggerBeforeCompletion(status);
@BeantransactionInterceptor()
@BeantransactionAttributeSource()
采取非事务方式执行
挂起当前事务
处理已有事务情况
开启事务
@Import(TransactionManagementConfigurationSelector.class)
构建事务
构建事务信息
对当前执行的事务 名称 耿隔离级别等记录进行修改 但是不创建新的事务
记录当前是否只读
PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 PROPAGATION_SUPPORTS -- 支持当前事务,如果当前没有事务,就以非事务方式执行。 PROPAGATION_MANDATORY -- 支持当前事务,如果当前没有事务,就抛出异常。 PROPAGATION_REQUIRES_NEW -- 新建事务,如果当前存在事务,把当前事务挂起。 PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 PROPAGATION_NEVER -- 以非事务方式执行,如果当前存在事务,则抛出异常。 PROPAGATION_NESTED -- 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
!txObject.hasConnectionHolder()
processCommit(defStatus);
读取当前执行的事务数据库连接对象 以及其他对象
if (con.getAutoCommit()) {\t\t\t\ttxObject.setMustRestoreAutoCommit(true);\t\t\t\tif (logger.isDebugEnabled()) {\t\t\t\t\tlogger.debug(\"Switching JDBC Connection [\" + con + \"] to manual commit\");\t\t\t\t}\t\t\t\tcon.setAutoCommit(false);\t\t\t}
PROPAGATION_NESTED
线程已存在事务
当异常与rollbackFor noRollbackFor 中指定的某种规则匹配时
!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()
for (TransactionSynchronization synchronization : suspendedSynchronizations) {\t\t\tsynchronization.suspend();\t\t}
如果传播方式为PROPAGATION_MANDATORY 为只能支持手动开启事务故会出现异常
txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)
@EnableTransactionManagement
如果这个连接时在本次调用中新建的进行资源绑定
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER
回滚true
绑定ThreadLocal资源
设置全局回滚标志
renturn
后置处理器BeanPostProcessor
回滚错误匹配校验
返回挂起对象
这些记录的信息可以在方法内部调用TransactionSynchronizationManaget.getXX方法获取到其中较为重要的是TransactionSynchronizationManager.initSynchronization();同步器 可以为当前的执行片段添加钩子方法在创建 提交 回滚 等重要节点回调执行同步器中定义的接口
执行同步器的suspend 挂起方法
判断是否存在全局回滚标志
返回事务对象
在EnableTransactionManagement通过Import导入了一个bean
重写获取pointCut方法
invokeAfterCompletion
isExistingTransaction(transaction)
false 匹配到不回滚规则
TransactionInterceptor
TransactionAttributeSource
@Transactional(propagation = Propagation.MANDATORY)
挂起事务
创建一个新的事务
这个功能在JDBC3.0后开始支持基于数据库的savepoint完成在一个数据库事务 中可以创建一个savepoint支持回滚到摸一个savepoint而不是全部回滚 ,在spring事务中如果一个呗@Tran修饰的方法的传播机制为NESTED 将会穿件一个savepoint
cleanupTransactionInfo(txInfo);
调用创建一个新的事务
通过@Bean的方式向spring容器中添加一个BeanFactoryTransactionAttributeSourceAdvisor 类型的 切面其中切面逻辑来自transactionInterceptor()方法产生的bean读取事务注解熟悉又transactionAttributeSource()产生的bean完成
返回事务
如果连接已经设置自动提交 则改为手动提交
transactionAdvisor()
TransactionStatus status = tm.getTransaction(txAttr);
采用Advise的Around 环绕方式进行带路,此处执行的是方法实际的逻辑
配置类上需要添加@EnableTransactionManagement注解
//如果当前事务没有指定名字 使用方法的权限定名为事务名if (txAttr != null && txAttr.getName() == null) { txAttr = new DelegatingTransactionAttribute(txAttr) { @Override public String getName() { return joinpointIdentification; } }; }
true
传播方式为 PROPAGATION_REQUIRED PROPAGATION_NESTED PROPAGATION_REQUIRES_NEW 新建一个事务
实现invoke(MethodInvocation invocation)
线程不存在事务
判断当前是否已经存在事务
txInfo.restoreThreadLocalStatus();
收藏
收藏
0 条评论
下一页