Spring基础课九:事务管理下

spring 事务源码

  1. DataSourceTransactionManager.DataSourceTransactionObject 中的 Connection,第一次是从数据源获取的,并会绑定到了 TransactionSynchronizationManager 的 threadLocal 成员变量 resource 中,之后获取,都是从成员变量 resource 中获取;

  2. transactionManager.getTransaction(transactionDefinition),用来开启一个事务,源码:

	--》TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);
	Object transaction = doGetTransaction();
	if (definition == null) {
		definition = new DefaultTransactionDefinition();
	}
	if (isExistingTransaction(transaction)) {
		return handleExistingTransaction(definition, transaction, debugEnabled);
	}
	// 构造一个transactionStatus
	DefaultTransactionStatus status = newTransactionStatus(
		definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
	doBegin(transaction, definition);
	prepareSynchronization(status, definition);
	return status;
  1. doGetTransaction(),获取事务对象 transaction;
	--doGetTransaction()
	DataSourceTransactionManager.DataSourceTransactionObject txObject = new 
		 DataSourceTransactionManager.DataSourceTransactionObject();
	// 设置是否允许嵌套
    txObject.setSavepointAllowed(this.isNestedTransactionAllowed());
    // 从TransactionSynchronizationManager的threadLocal成员变量中获取ConHolder,第一次获取应该是null
    ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager
    	.getResource(this.obtainDataSource());
    txObject.setConnectionHolder(conHolder, false);
    return txObject;
  1. isExistingTransaction(transaction),判断是否存在事务,判断 transaction 中的 connHolder 是否存在,第一次应该是不存在,如果存在,按照传播方式,加入事务或抛出异常等不同操作;
	--isExistingTransaction(transaction)
    return txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive();
  1. doBegin(transaction, definition),从数据源获取连接,并设置到事务对象 transaction 中;
	--doBegin(transaction, definition)
	// 从数据源获取一个连接
	Connection newCon = this.obtainDataSource().getConnection();
	// 将连接设置到 transaction 中,并设置一些标志位,隔离级别
    txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
	txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
    con = txObject.getConnectionHolder().getConnection();
    Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
    txObject.setPreviousIsolationLevel(previousIsolationLevel);
	con.setAutoCommit(false);
	// 如果是第一次获取到的连接,将 datasource 和 connection 的键值对,
	// 设置到 TransactionSynchronizationManager 的 threadLocal 成员变量中
	// 保证了同一个线程从 TransactionSynchronizationManager 获取到的 resource 是同一个,不同线程间互不干扰
    if (txObject.isNewConnectionHolder()) {     	
    TransactionSynchronizationManager.bindResource
    	(this.obtainDataSource(),txObject.getConnectionHolder());
    }
  1. prepareSynchronization(status, definition),判断如果是新事务,给 TransactionSynchronizationManager 设置一些标志位,这些标志位也都是 threadLocal 封装的,handleExistingTransaction(definition, transaction, debugEnabled),用于处理事务的传播方式;

  2. commit(TransactionStatus status),提交事务

	--prepareForCommit(status);
	triggerBeforeCommit(status);
	doCommit(status);
	triggerAfterCommit(status);
  1. doCommit(status),具体提交事务,rollback 和 commit 的逻辑类似;
	--doCommit(status)
	// 获取封装在DataSourceTransactionManager.DataSourceTransactionObject中的Connection,
	// 调用其commit来提交事务
	Connection con = txObject.getConnectionHolder().getConnection();
	con.commit();

事务使用方式

  1. 基本上底层均是使用jdbc控制事务的方式,推荐使用spring事务,更方便和通用;

  2. 尽量避免jdbc和orm框架混合操作数据库;

  3. 推荐使用spring提供TransactionTemplate模板类和注解方式使用事务,如果需要获取数据库连接,需要通过DataSourceUtils工具类;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章