3.ibatis4种事务类型浅析

ibatis中Transaction有四个实现类

其中spring的SqlMapClientFactoryBean类中

private Class transactionConfigClass = ExternalTransactionConfig.class;

public SqlMapClientFactoryBean() {
this.transactionConfigProperties = new Properties();
this.transactionConfigProperties.setProperty("SetAutoCommitAllowed", "false");
}

1.ExternalTransaction

  • 不指定事务类型时,默认使用此类型的事务;
  • 在调用getConnection()时才去建立数据库连接;
  • AutoCommit默认为true;
  • commit()和rollback()均为空实现;
public ExternalTransaction(DataSource ds, boolean defaultAutoCommit, boolean setAutoCommitAllowed, int isolationLevel) throws TransactionException {
this.dataSource = ds;
if (this.dataSource == null) {
throw new TransactionException("ExternalTransaction initialization failed. DataSource was null.");
} else {
this.defaultAutoCommit = defaultAutoCommit;
this.setAutoCommitAllowed = setAutoCommitAllowed;
this.isolationLevel.setIsolationLevel(isolationLevel);
}
}
public Connection getConnection() throws SQLException, TransactionException {
if (this.connection == null) {
this.init();
}

return this.connection;
}
private void init() throws SQLException, TransactionException {
this.connection = this.dataSource.getConnection();
if (this.connection == null) {
throw new TransactionException("ExternalTransaction could not start transaction. Cause: The DataSource returned a null connection.");
} else {
this.isolationLevel.applyIsolationLevel(this.connection);
if (this.setAutoCommitAllowed && this.connection.getAutoCommit() != this.defaultAutoCommit) {
this.connection.setAutoCommit(this.defaultAutoCommit);
}

if (connectionLog.isDebugEnabled()) {
this.connection = ConnectionLogProxy.newInstance(this.connection);
}

}
}

2.JdbcTransaction

  • 需要在配置文件中指定transactionConfigClass为此类型;
  • 在调用getConnection()时才去建立数据库连接,同上;
  • AutoCommit默认为false;
  • 由TransactionManager统一管理,在执行过程中自动调用commit()和rollback()提交或者回滚;

<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">

<property name="configLocation" value="classpath:sql-map-config.xml"></property>
<property name="dataSource" ref="dataSource"></property>
<property name="transactionConfigClass" value="com.ibatis.sqlmap.engine.transaction.jdbc.JdbcTransactionConfig"></property>

</bean>

 

public void commit() throws SQLException, TransactionException {
if (this.connection != null) {
this.connection.commit();
}

}

public void rollback() throws SQLException, TransactionException {
if (this.connection != null) {
this.connection.rollback();
}

}

 

3.JtaTransaction

  Todo:暂时还未看到,待补充。。。。。。。。。。。。。。。

4.UserProviderTransaction

  • 不能在配置文件中指定此类型的事务,需要先有Connection的情况下才可以使用此类型,即:在TransactionManager的begin()方法中不会new出此类型的事务;
  • AutoCommit为之前获取的Connection设置的值,默认为true;
  • commit()和rollback()没有发现哪里使用;
  • 在使用spring的SqlMapClientTemplate操作时,会根据获取到的SpringCon组装一个UserProviderTransaction,此时配置文件中设置的上述三种事务类型均失效;

个人理解:

   如果外层不手动配置事务,此事务的作用仅仅是提供了一个connection而已,此时connection.getAutoCommit()==true,并没有真正起到事务的作用;

   如果外层配置了事务,此事务跟外层配置的事务使用同一个connection,外层事务会设置connection的Autocommit=false,真正起作用的还是外层的事务。

public UserProvidedTransaction(Connection connection) {
if (connectionLog.isDebugEnabled()) {
this.connection = ConnectionLogProxy.newInstance(connection);
} else {
this.connection = connection;
}

}
public Connection getConnection() throws SQLException, TransactionException {
return this.connection;
}

参考流程:




 


当外部配置事务时,开启事务时会先获取一个connection
DataSourceTransactionManager.java






sqlMapClientTemplate获取连接时

 

posted on 2018-12-29 15:50  Hleaves  阅读(695)  评论(0编辑  收藏  举报