spring+ibatis批处理解决
程序员文章站
2022-07-09 13:24:20
...
为了实现日志批处理提交,这几天详细研究了ibatis的事务和批处理。
直接上代码,然后说结论吧。spring版本3.1 + ibatis2.3.4
配置
java代码:
总结: 上面第一种方式中的事务,只起着开启批处理的作用,没有其他作用。另外网上有人推荐在第一种方法上添加@Transational来开启事务,这种方法能开启事务,的确能打开事务,但是没批处理,主要是spring接管的事务会话,不能自己操作的sqlMapClient很好的衔接起来。同时事务侵入代码+不能回滚,所以要是采用事务的话,还是不要采用这种方法。要
采用事务的话,最好采用上面第二方法。
log4j配置文件,方便前端监控,事务和批处理的情况
数据库端,采用mysql的话可以mysqlbinlog查看二进制日志查看事务提交情况,bingin...commit代表一个事务
直接上代码,然后说结论吧。spring版本3.1 + ibatis2.3.4
配置
<bean id="log.sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> <property name="configLocation" value="classpath:config/db/ibatis/log-sqlmap-config.xml" /> <property name="dataSource" ref="log.dataSource" /> </bean> <bean id="log.transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="log.dataSource" /> </bean> <!-- enable transaction demarcation with annotations --> <tx:annotation-driven /> <!-- DAO配置 --> <bean id="logDAO" class="com.X.LogDAO"> <property name="sqlMapClient" ref="log.sqlMapClient" /> </bean>
java代码:
/*** * ibatis的批处理必须放在事务内,此处事务的作用只是起着开启批处理的作用, 实际上每个sql一个事务 * 目的:使用批处理,而不使用事务,故选择此方法 * */ public void batchSave(Queue<BaseLog> logQueue) { if (logQueue == null) return; long startTime = System.currentTimeMillis(); int queueSize = logQueue.size(); if (queueSize == 0) return; SqlMapClientTemplate sqlMapClientTemplate = getSqlMapClientTemplate(); SqlMapClient sqlMapClient = sqlMapClientTemplate.getSqlMapClient(); try { sqlMapClient.startTransaction(); sqlMapClient.startBatch(); int insertNum = 0; for (int i = 0; i < queueSize; i++) { BaseLog log = logQueue.poll(); if (log == null) break; insertNum++; String saveMethod = "insert" + log.getClass().getSimpleName(); sqlMapClient.insert(saveMethod, log); if (insertNum % BATCH_SIZE == 0) { sqlMapClient.executeBatch(); sqlMapClient.startBatch(); } } sqlMapClient.executeBatch(); sqlMapClient.commitTransaction(); long logTime = System.currentTimeMillis() - startTime; logger.info("[记录日志] [大小:" + insertNum + "] [时间:" + logTime + "] [succ]"); } catch (SQLException e) { logger.error("[记录日志] [fail]", e); } finally { try { sqlMapClient.endTransaction(); } catch (SQLException e) { logger.error("[EndLogTransaction] [error]", e); } } } /** * spring首选批处理提交方式,失败的话,会自动回滚 * * @param logQueue */ @SuppressWarnings({ "unchecked", "rawtypes" }) @Transactional(value = "log.transactionManager") public void batchSaveX(final Queue<BaseLog> logQueue) { // 执行回调 getSqlMapClientTemplate().execute(new SqlMapClientCallback() { // 实现回调接口 public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException { int queueSize = logQueue.size(); if (queueSize == 0) return 0; long startTime = System.currentTimeMillis(); int count = 0, total = 0; // 开始批处理 executor.startBatch(); for (int i = 0; i < queueSize; i++) { BaseLog baseLog = logQueue.poll(); // 插入操作 String saveMethod = "insert" + baseLog.getClass().getSimpleName(); executor.insert(saveMethod, baseLog); count++; if (count % BATCH_SIZE == 0) { total += executor.executeBatch(); executor.startBatch(); } } // 执行批处理 total += executor.executeBatch(); long logTime = System.currentTimeMillis() - startTime; logger.info("[记录日志2] [大小:" + total + "] [时间:" + logTime + "] [succ]"); return new Integer(total); } }); }
总结: 上面第一种方式中的事务,只起着开启批处理的作用,没有其他作用。另外网上有人推荐在第一种方法上添加@Transational来开启事务,这种方法能开启事务,的确能打开事务,但是没批处理,主要是spring接管的事务会话,不能自己操作的sqlMapClient很好的衔接起来。同时事务侵入代码+不能回滚,所以要是采用事务的话,还是不要采用这种方法。要
采用事务的话,最好采用上面第二方法。
log4j配置文件,方便前端监控,事务和批处理的情况
<logger name="java.sql"> <level value="debug" /> </logger> <logger name="org.springframework.orm"> <level value="debug" /> </logger> <logger name="org.springframework.jdbc"> <level value="debug" /> </logger>
数据库端,采用mysql的话可以mysqlbinlog查看二进制日志查看事务提交情况,bingin...commit代表一个事务
上一篇: zookeeper迁移方案
下一篇: samba使用总结
推荐阅读
-
Wordcloud安装失败解决方案
-
error while loading shared libraries: libmysqlclient.so.18解决方法
-
Win8.1系统不能运行使命召唤ol怎么办?win8.1不能玩使命召唤的解决方法
-
WinXp系统音频驱动有杂音怎么办?WinXp系统音频驱动有杂音的解决方法
-
php substr截断中文半个汉字乱码问题的解决方法
-
哈哈零兽携新品亮相广州新零售展 启动全场景解决方案
-
把握客户生命周期全节点,商派推互联网商业平台解决方案
-
injector 用PHP函数解决SQL injection
-
PHP 发送邮件。该怎么解决
-
steam打不开怎么办?steam打不开的解决方法