当前位置: 首页 > article >正文

Spring 事务 数据库连接获取和释放原理

##调试demo

@Service
public class CrmUserService {

    @Autowired
    private CrmUserDao crmUserDao;

    @Autowired
    private CrmLoginLogDao crmLoginLogDao;

    @Transactional
    public void getUser() {
        System.out.println("Service::"+Thread.currentThread().getName());
        System.out.println(crmUserDao.getUser());
        System.out.println(crmLoginLogDao.getLoginLog());
    }

}


@Mapper
public interface CrmLoginLogDao {

    @Select("select user_name from login_log")
    public List<String> getLoginLog();

}


@Mapper
//@DS("slave")
public interface CrmUserDao extends BaseMapper {

//    @Select("select version_code from t_app_update")
//    @Select("select pg_sleep(1200)")
    @Select("select user_name from user_info")
    public List<String> getUser();

}

##目标方法被代理

##创建事务 createTransactionIfNecessary

##tm.getTransaction

##获取事务doGetTransaction()

##获取事务数据库连接,ConnectionHolder  TransactionSynchronizationManager.getResource(obtainDataSource())

##获取数据源TransactionSynchronizationUtils.unwrapResourceIfNecessary(key)

##获取Object value = doGetResource(actualKey)

private static final ThreadLocal<Map<Object, Object>> resources =       new NamedThreadLocal<>("Transactional resources");

线程首次获取到值为空

##transaction  中属性ConnectionHolder为空

##开始事务

##判断txObject.hasConnectionHolder()是否有ConnectionHolder 为false,创建ConnectionHolder

##ConnectionHolder 设置到DataSourceTransactionManager,连接事务自动提交改为false

##事务中第一次sql查询,调用mapper查询

public abstract java.util.List com.newland.mi.dao.CrmUserDao.getUser()

##获取连接

Connection connection = getConnection(statementLog);

##从事务中获取连接

Connection connection = transaction.getConnection()

##从之前ConnectionHolder获取连接

return conHolder.getConnection();

##事务中第二次sql查询,调用mapper查询

public abstract java.util.List com.newland.mi.dao.CrmLoginLogDao.getLoginLog()

##从事务中获取连接

##查询完成,清空事务

cleanupTransactionInfo(txInfo);

##提交事务,释放连接

commitTransactionAfterReturning(txInfo);

##提交事务

##清理资源

cleanupAfterCompletion(status);

##清理

##设置事务自动提交,设置事务隔离级别为空

con.setAutoCommit(true);

DataSourceUtils.resetConnectionAfterTransaction(       con, txObject.getPreviousIsolationLevel(), txObject.isReadOnly());

##释放数据库连接回连接池

DataSourceUtils.releaseConnection(con, this.dataSource);

##清空ConnectionHolder  的currentConnection为空

this.currentConnection = null;

##数据库连接放回连接池

 doCloseConnection(con, dataSource);

 

##数据库连接池

 ##connection.recycle();

 

##最终放入池内

 ##加锁,放回DruidConnectionHolder[]数组

private volatile DruidConnectionHolder[] connections;

 ##放入数组最后一个位置
 incrementPoolingCount() 数组长度加1


http://www.kler.cn/a/287690.html

相关文章:

  • 无人机动力系统测试-实测数据与CFD模拟仿真数据关联对比分析
  • 风电电力系统低碳调度论文阅读第一期
  • 【java】链表:判断链表是否成环
  • 【Pikachu】XML外部实体注入实战
  • 2024-11-16 串的存储结构
  • 游戏引擎学习第八天
  • 网络安全的历史
  • 基于my Batis优化图书管理系统(总)
  • 通用后台管理系统实战演示(Vue3 + element-plus)汇总篇二
  • 设计模式之生成器方法
  • css揭秘 7 结构与布局
  • Swin Transformer: Hierarchical Vision Transformer using Shifted Windows
  • 使用API有效率地管理Dynadot域名,添加账户中的联系人信息
  • Java中Object的常用方法
  • 专利复现_基于ngboost和SHAP值可解释预测方法
  • 【html】新建一个html并且在浏览器运行
  • 零域(微隔离)详述
  • docker4
  • ios 企业签名证书购买_iOS苹果企业签名须知
  • Spring源码浅析の循环依赖
  • 泰山派的小手机后续(2)
  • upload-labs通关攻略
  • Clickhouse集群化(四)使用clickhouse-operator部署clickhouse集群
  • vs中在工具箱添加自定义控件numberTextBox
  • 链表题总结
  • 使用MySql