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

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值