spring ibatis事务一个误区分析

先看段经典的ibatis spring配置,注意我的配置中没有配置spring的声明式事务:

<!-- ======================================================================== -->
<!-- DataSource定义。 -->
<!-- ======================================================================== -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="**" />
<property name="url" value="**" />
<property name="username" value="**" />
<property name="password" value="**" />
<property name="defaultAutoCommit" value="true or false" /> <!---请先不关心这个配置,后面会说道--
</bean>

<!-- ======================================================================== -->
<!-- TransactionManager定义。 -->
<!-- ======================================================================== -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager" />
</bean>

<!-- ======================================================================== -->
<!-- iBatis SQL map定义。 -->
<!-- ======================================================================== -->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:META-INF/sqlmap/sqlmap-config.xml" />
</bean>

面对上面的配置,看下面的代码有什么问题:

try {
sqlMapClient.startTransaction();
//...do something
sqlMapClient.commitTransaction();
}
catch(Exception e) {
try {
client.endTransaction();
} catch (Exception ex) {

}
}

表面上没有问题,错!问题很大~~~看下面SqlMapClientFactoryBean源代码

import com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig;
public class SqlMapClientFactoryBean implements FactoryBean<SqlMapClient>, InitializingBean {
//...省略其它
private Class transactionConfigClass = ExternalTransactionConfig.class;

public void afterPropertiesSet() throws Exception {
//...
try {
//读取配置的ibatis映射
this.sqlMapClient = ...;

if (this.dataSource != null) {
//这个地方关键的很,实例化了ExternalTransactionConfig,事务的提交取决这里。这里实际实例化的是ExternalTransactionConfig对象,而这个对象的内容,请看下面
TransactionConfig transactionConfig = (TransactionConfig) this.transactionConfigClass.newInstance();
DataSource dataSourceToUse = this.dataSource;
if (this.useTransactionAwareDataSource && !(this.dataSource instanceof TransactionAwareDataSourceProxy)) {
dataSourceToUse = new TransactionAwareDataSourceProxy(this.dataSource);
}
transactionConfig.setDataSource(dataSourceToUse);
transactionConfig.initialize(this.transactionConfigProperties);
//将事务配置应用到sqlMapClient
applyTransactionConfig(this.sqlMapClient, transactionConfig);
}
}
//....
}
}

再看下ExternalTransactionConfig代码:

public class ExternalTransactionConfig extends BaseTransactionConfig {

private boolean defaultAutoCommit = false;
private boolean setAutoCommitAllowed = true;
//这里是spring启动事务调用的方法
public Transaction newTransaction(int transactionIsolation) throws SQLException, TransactionException {
return new ExternalTransaction(dataSource, defaultAutoCommit, setAutoCommitAllowed, transactionIsolation);
}
//...省略
}

再看ExternalTransaction:

public class ExternalTransaction implements Transaction {
//...其它省略
//ibatis默认使用外部事务提交的时候是空实现!回滚也是。
public void commit() throws SQLException, TransactionException {
}

public void rollback() throws SQLException, TransactionException {
}
}

到此真相大白,事务没有任何作用~~
也就是说如果使用spring集成管理ibatis,ibatis的事务将完全交由外部spring进行管理,ibatis不作为!

为什么有时候似乎数据库里面也插入了数据?哦,请看下面的属性配置:

<property name="defaultAutoCommit" value="true or false" />

这个属性的配置起了关键作用,如果配置为true,会自行提交,这也就不难解释为什么有数据了,而一旦配置成false,数据却一条也没有了~•~•
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值