iBatis框架做batch处理的问题
操作方法
- 01
下面达内it培训以一个案例来讲解一下iBatis框架做batch处理的问题,希望大家喜欢。 最近,同事的一个项目用Spring+iBatis做为数据持久层框架,MySQL数据存储。项目发布不久就遇到了严重的性能问题,因此决定采用batch的方式提交数据。我以前的一篇文章:里详细的介绍了iBatis框架做batch处理的方式以及可能存在的问题和性能优化,因此同事参考这偏文章对项目进行了改造,引入了batch处理机制。但事情并不顺利,在只有2000条数据的情况下,用iBatis框架做batch处理和不做batch所消耗的时间居然没有区别,平均都要50秒左右。而我在做测试的时候如果做batch仅仅需要1秒,甚至更少的时间。真是见鬼了,难道是Spring在搞鬼?因为我的测试和同事的项目唯一的区别就是我是直接使用iBatis的SqlMapClient,而同事的项目是使用Spring来获取SqlMapClient的实例。仔细检查了一下朋友的数据源配置,也没有发现什么问题。如下: <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.JDBC.Driver"/> <property name="url" value="jdbc:mysql://localhost/test"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean> <bean id="sqlMapClient" class="org.springFramework.orm.ibatis.SqlMapClientFactoryBean"> <property name="configLocation" value="SqlMapConfig.XML"/> <property name="dataSource" ref="dataSource"/> </bean> 就在万般无奈的时候,突然想到一个问题:如果JDBC的AutoCommit属性被设置为true的话,那即便是按照batch的方式来写程序,也是徒劳的,每一条语句都会直接执行。于是抱着试试看的态度执行了下面的语句: System.out.println("当前事物状态: " + sqlMapClient.getDataSource().getConnection().getAutoCommit()); 果然不出所料,输出的值为:true,难怪batch不可用!问题找到了,如何解决呢?尝试在batch语句执行前手工设置autoCommit属性为false,如:sqlMapClient.getDataSource().getConnection().setAutoCommit(false);结果不好用,于是查看了一下org.apache.commons.dbcp.BasicDataSource的源代码,发现它的defaultAutoCommit属性默认值为true,这就难怪spring获取的SqlMapClient的autoCommit属性为true了,既然问题找到了, 解决起来就容易多了,只需要在上面的datasource配置中增加一行:<property name="defaultAutoCommit" value="false"/>就可以了。 达内IT总结:iBatis默认的autoCommit属性为false,因此用iBatis框架做batch处理的时候基本不会遇到什么问题;在Spring环境下,要看具体DataSource的配置。