##调试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




















