目录

DataSourceTransactionManager

doGetTransaction

isExistingTransaction

doBegin

doCommit

doSuspend

doRollback

doCleanupAfterCompletion

DataSourceUtils

ConnectionSynchronization

suspend


JDBC事务时Spring 事务的具体实现。

DataSourceTransactionManager

public class DataSourceTransactionManager extends AbstractPlatformTransactionManagerimplements ResourceTransactionManager, InitializingBean {//数据库DataSourceprivate DataSource dataSource;private boolean enforceReadOnly = false;
}

doGetTransaction

构造DataSourceTransactionObject,存储ConnectionHolder

 @Overrideprotected Object doGetTransaction() {DataSourceTransactionObject txObject = new DataSourceTransactionObject();txObject.setSavepointAllowed(isNestedTransactionAllowed());
//通过DataSource获取ConnectionHolder ConnectionHolder conHolder =(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
//DataSourceTransactionObject设置ConnectionHolder txObject.setConnectionHolder(conHolder, false);return txObject;}

isExistingTransaction

如果存在getConnectionHolder,并且有活跃事务,则表示已存在事务。

 @Overrideprotected boolean isExistingTransaction(Object transaction) {DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;return (txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive());}

doBegin

主要功能就是保存Connection,设置事务状态。

@Overrideprotected void doBegin(Object transaction, TransactionDefinition definition) {//获取事务对象。DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;Connection con = null;try {//如果没有ConnectionHolder,则构造一个。if (!txObject.hasConnectionHolder() ||txObject.getConnectionHolder().isSynchronizedWithTransaction()) {Connection newCon = obtainDataSource().getConnection();if (logger.isDebugEnabled()) {logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");}txObject.setConnectionHolder(new ConnectionHolder(newCon), true);}txObject.getConnectionHolder().setSynchronizedWithTransaction(true);//从事务对象获取Connectioncon = txObject.getConnectionHolder().getConnection();//事务准备,返回隔离级别,并设置到当前事务对象。Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);txObject.setPreviousIsolationLevel(previousIsolationLevel);txObject.setReadOnly(definition.isReadOnly());// Switch to manual commit if necessary. This is very expensive in some JDBC drivers,// so we don't want to do it unnecessarily (for example if we've explicitly// configured the connection pool to set it already).//是否自动提交。如果是自动提交,则改为手动提交。if (con.getAutoCommit()) {txObject.setMustRestoreAutoCommit(true);if (logger.isDebugEnabled()) {logger.debug("Switching JDBC Connection [" + con + "] to manual commit");}con.setAutoCommit(false);}//准备提交。prepareTransactionalConnection(con, definition);//激活当前事务。txObject.getConnectionHolder().setTransactionActive(true);//设置超时。int timeout = determineTimeout(definition);if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {txObject.getConnectionHolder().setTimeoutInSeconds(timeout);}// 如果是新建的,则绑定到当前线程。if (txObject.isNewConnectionHolder()) {TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());}}catch (Throwable ex) {if (txObject.isNewConnectionHolder()) {DataSourceUtils.releaseConnection(con, obtainDataSource());txObject.setConnectionHolder(null, false);}throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);}}

doCommit

通过事务的Connection,调用commit方法,提交事务。

@Overrideprotected void doCommit(DefaultTransactionStatus status) {
//从事务对象中获取Connection,调用Connection的提交。DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();Connection con = txObject.getConnectionHolder().getConnection();if (status.isDebug()) {logger.debug("Committing JDBC transaction on Connection [" + con + "]");}try {con.commit();}catch (SQLException ex) {throw new TransactionSystemException("Could not commit JDBC transaction", ex);}}

doSuspend

Connection设置为null,解绑资源

 @Overrideprotected Object doSuspend(Object transaction) {DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;txObject.setConnectionHolder(null);
//当前线程解绑资源,return TransactionSynchronizationManager.unbindResource(obtainDataSource());}@Overrideprotected void doResume(@Nullable Object transaction, Object suspendedResources) {
//重新绑定资源TransactionSynchronizationManager.bindResource(obtainDataSource(), suspendedResources);}

doRollback

调用Connection.rollback()方法回滚事务。

@Overrideprotected void doRollback(DefaultTransactionStatus status) {DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();Connection con = txObject.getConnectionHolder().getConnection();if (status.isDebug()) {logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");}try {con.rollback();}catch (SQLException ex) {throw new TransactionSystemException("Could not roll back JDBC transaction", ex);}}

doCleanupAfterCompletion

如果新事务,解绑资源。恢复状态:自动提交、connection。

 @Overrideprotected void doCleanupAfterCompletion(Object transaction) {DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;// Remove the connection holder from the thread, if exposed.if (txObject.isNewConnectionHolder()) {TransactionSynchronizationManager.unbindResource(obtainDataSource());}// Reset connection.Connection con = txObject.getConnectionHolder().getConnection();try {if (txObject.isMustRestoreAutoCommit()) {con.setAutoCommit(true);}DataSourceUtils.resetConnectionAfterTransaction(con, txObject.getPreviousIsolationLevel(), txObject.isReadOnly());}catch (Throwable ex) {logger.debug("Could not reset JDBC Connection after transaction", ex);}if (txObject.isNewConnectionHolder()) {if (logger.isDebugEnabled()) {logger.debug("Releasing JDBC Connection [" + con + "] after transaction");}DataSourceUtils.releaseConnection(con, this.dataSource);}txObject.getConnectionHolder().clear();}

DataSourceUtils

DataSourceUtils,工具类,用于辅助DataSource操作。主要就是Connection相关操作,

ConnectionSynchronization

用于事务同步。

private final ConnectionHolder connectionHolder;private final DataSource dataSource;private int order;private boolean holderActive = true;

suspend

解绑datasource资源,释放connection。

 @Overridepublic void suspend() {if (this.holderActive) {TransactionSynchronizationManager.unbindResource(this.dataSource);if (this.connectionHolder.hasConnection() && !this.connectionHolder.isOpen()) {// Release Connection on suspend if the application doesn't keep// a handle to it anymore. We will fetch a fresh Connection if the// application accesses the ConnectionHolder again after resume,// assuming that it will participate in the same transaction.releaseConnection(this.connectionHolder.getConnection(), this.dataSource);this.connectionHolder.setConnection(null);}}}
 @Overridepublic void resume() {if (this.holderActive) {TransactionSynchronizationManager.bindResource(this.dataSource, this.connectionHolder);}}
@Overridepublic void beforeCompletion() {// Release Connection early if the holder is not open anymore// (that is, not used by another resource like a Hibernate Session// that has its own cleanup via transaction synchronization),// to avoid issues with strict JTA implementations that expect// the close call before transaction completion.if (!this.connectionHolder.isOpen()) {TransactionSynchronizationManager.unbindResource(this.dataSource);this.holderActive = false;if (this.connectionHolder.hasConnection()) {releaseConnection(this.connectionHolder.getConnection(), this.dataSource);}}}@Overridepublic void afterCompletion(int status) {// If we haven't closed the Connection in beforeCompletion,// close it now. The holder might have been used for other// cleanup in the meantime, for example by a Hibernate Session.if (this.holderActive) {// The thread-bound ConnectionHolder might not be available anymore,// since afterCompletion might get called from a different thread.TransactionSynchronizationManager.unbindResourceIfPossible(this.dataSource);this.holderActive = false;if (this.connectionHolder.hasConnection()) {releaseConnection(this.connectionHolder.getConnection(), this.dataSource);// Reset the ConnectionHolder: It might remain bound to the thread.this.connectionHolder.setConnection(null);}}this.connectionHolder.reset();}

Spring Boot Transaction 源码解析(二)相关推荐

  1. Spring Boot Transaction 源码解析(一)

    目录 PlatformTransactionManager TransactionStatus DefaultTransactionStatus AbstractPlatformTransaction ...

  2. spring aop 注入源码解析

    spring aop 注入源码解析 aop启动 AbstractApplicationContext.java @Overridepublic void refresh() throws BeansE ...

  3. spring aop 注入源码解析 1

    spring aop 注入源码解析 aop启动 AbstractApplicationContext.java @Overridepublic void refresh() throws BeansE ...

  4. Spring 之 @Cacheable 源码解析(上)

    一.@EnableCaching 源码解析 当要使用 @Cacheable 注解时需要引入 @EnableCaching 注解开启缓存功能.为什么呢?现在就来看看为什么要加入 @EnableCachi ...

  5. Spring 之 @Cacheable 源码解析(下)

    CacheInterceptor 缓存切面处理逻辑 接着上篇 Spring 之 @Cacheable 源码解析(上) 说起,代理对象已经创建成功,接着分析调用流程.那么应该从哪里入手呢?当然是去看 A ...

  6. 【深度学习模型】智云视图中文车牌识别源码解析(二)

    [深度学习模型]智云视图中文车牌识别源码解析(二) 感受 HyperLPR可以识别多种中文车牌包括白牌,新能源车牌,使馆车牌,教练车牌,武警车牌等. 代码不可谓不混乱(别忘了这是职业公司的准产品级代码 ...

  7. Spring Cloud Gateway 源码解析(3) —— Predicate

    目录 RoutePredicateFactory GatewayPredicate AfterRoutePredicateFactory RoutePredicateHandlerMapping Fi ...

  8. spring 多线程 事务 源码解析(一)

    大家好,我是烤鸭: 今天分享的是spring 多线程事务源码分析. 环境: spring-jdbc 5.0.4.REALEASE 今天分享一下spring事务的方法,这一篇还没涉及到多线程. 简单说一 ...

  9. erlang下lists模块sort(排序)方法源码解析(二)

    上接erlang下lists模块sort(排序)方法源码解析(一),到目前为止,list列表已经被分割成N个列表,而且每个列表的元素是有序的(从大到小) 下面我们重点来看看mergel和rmergel ...

最新文章

  1. 独家 | TensorFlow 2.0将把Eager Execution变为默认执行模式,你该转向动态计算图了...
  2. Spring Workflow
  3. xhtml使用style属性
  4. zuulfilter添加例外_SpringCloud之Zuul 自定义filter
  5. zeppelin的安装与使用
  6. WIN 10 安装 Hadoop 2.7.7 + Spark 2.4.7 记录
  7. java concurrent int_java.util.concurrent.AtomicInteger
  8. 程序员等级测试,你不进来试试么?听说等级高的都进一线bat了!
  9. 微信小程序插件---表单验证篇
  10. 损失函数与代价函数区别
  11. MCU控制继电器的电路详解
  12. node的HTPP请求
  13. EPLAN2022——创建项目和图纸
  14. linux pwm控制蜂鸣器 滴滴_第七章----pwm蜂鸣器
  15. 高通|AR扫描图片播放视频
  16. 《数据库原理与应用》(第三版)习题参考答案
  17. 汉诺塔的递归逐步详解
  18. W3C标准包括什么?
  19. Java excel导入导出
  20. 【Axure教程】中继器版投票原型

热门文章

  1. ZOJ 1161 Gone Fishing
  2. asp.net中生命周期的浅析
  3. 第6节 三个败家子(6)——很黄很暴力的刘禅
  4. 重新开始我的园子生活了
  5. 你在使用Gmail,Wallop,MSN Spaces,Three Degrees吗?
  6. Android之Handler用法总结(1)
  7. Linux字符设备驱动框架
  8. Django Channels 入门指南
  9. 【博客美化】08.添加扩大/缩小浏览区域大小 按钮
  10. yield return关键字怎么使用?