- 浏览: 88269 次
- 性别:
- 来自: 北京
最新评论
-
pcpig:
如果不能写的话,尝试修改一下配置文件cat /etc/sel ...
samba使用总结 -
pcpig:
简单启动脚本#!/bin/sh
PROJECT="p ...
Tomcat启动参数修改 -
pcpig:
基于ant的项目发布base_dir=`dirname $0` ...
项目发布脚本 -
pcpig:
同事提醒:网络通讯用gzip由于没有文件结构,压缩效果更好 p ...
消息压缩和解压缩 -
pcpig:
上面第一种方法有问题,第二种方法才是正确的。第一种方法,上线后 ...
spring+ibatis批处理解决
为了实现日志批处理提交,这几天详细研究了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代表一个事务
评论
1 楼
pcpig
2013-04-06
上面第一种方法有问题,第二种方法才是正确的。
第一种方法,上线后很快就导致数据库连接被关闭,抛出如下异常
而第二种方法,上线后表现很不错,不仅运行很正常,而且性能也比第一种好。
ps:保留错误的方法,权当给大家提个醒。另外事务没有想象中那么耗性能,凡事还是要亲自动手尝试一下才有确切的体会。
第一种方法,上线后很快就导致数据库连接被关闭,抛出如下异常
--- Check the statement or the result map. --- Cause: java.sql.SQLException: Connection has already been closed. at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeUpdate(MappedStatement.java:107) at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.insert(SqlMapExecutorDelegate.java:393) at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.insert(SqlMapSessionImpl.java:82) at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.insert(SqlMapClientImpl.java:58)
而第二种方法,上线后表现很不错,不仅运行很正常,而且性能也比第一种好。
ps:保留错误的方法,权当给大家提个醒。另外事务没有想象中那么耗性能,凡事还是要亲自动手尝试一下才有确切的体会。
发表评论
-
我对dubbo monitor的认识
2020-02-14 14:53 578dubbo monitor的功能总结,主要为4块。 1:m ... -
我对互联网监控的理解
2020-01-20 16:49 526互联网服务是否运行正常,从监控的角度需要考虑以下几个方面 ... -
同一个java工程打两个不同的包
2016-08-18 18:01 1226目的:1、打一个普通java包,用于spring aop ... -
AOP的三种实现
2016-08-18 17:53 6721、利用Spring AOP 2、所依赖的包是普通java编译 ... -
大量close_wait以及调用ip地址错误获取方法引发的故障
2014-05-12 17:43 1867记录一下这几天帮助兄弟项目组解决的几个问题 工程:网关服务器 ... -
在线编辑html的网站
2014-02-11 11:34 812提供给产品人员使用,方便其生成html代码 http://ki ... -
cached过高,导致load高的问题
2013-09-25 20:42 3176同事反映linux操作系统无端的大量内存被“cache ... -
spring中bean的更新方法及在不同环境下的问题
2013-09-25 20:21 1331如果spring中bean的配置信息是放在xml中,如果修改了 ... -
samba使用总结
2013-09-10 14:17 9471、安装 #rpm -qa | grep samba ... -
开发经验、流程总结
2013-09-09 17:41 7031、原则: 代码应该尽早提交 提交前提:所提交的代码不会影响其 ... -
子网掩码错误导致的问题
2013-09-09 16:15 1106背景:pc ip:10.X 测试机ip:1.69 1.70 ... -
Btrace实战
2013-08-22 16:36 1345btrace可以对是针对java平台的一个动态追踪工具。简单点 ... -
消息压缩和解压缩
2013-06-19 16:42 1228无线开发时,一方面出于给玩家节省流量的考虑,一方面为了 ... -
log4j配置热加载
2013-06-18 19:04 1722log4j热加载的原理网上说的很多,我就不多说了。主要整理一下 ... -
复制文件的脚本(linux+windowx)
2013-06-06 16:36 1090功能:把指定文件夹(不包括)下的所有东西复制到指定文件夹下。 ... -
liunx下通讯协议监控
2013-05-22 17:42 818tcpdump是linux下非常强大的协议层分析工具,结合它可 ... -
比较难查找的死循环(java)
2013-05-20 16:35 1683项目的开发人员找到我说游戏挂掉了。 症状:1、客户端能跟服务器 ... -
java.lang.OutOfMemoryError: unable to create new native thread
2013-05-16 19:50 1645bootstrap = new ServerBootstra ... -
eclipse、maven、tomcat下建Dynamic web工程
2013-04-18 11:56 892在eclipse中通过svn下载的maven(java)项目是 ... -
数据库配置优化
2013-04-06 22:01 877存储引擎主要是:innodb,计划提供2G内存用于Mysql运 ...
相关推荐
很好的spring+ibatis事务的配置文档.
struts2+spring+ibatis+mysql AOP日志管理,异常捕获 tomcat6.0+jdk1.6
struts+spring+ibatis做的一个增删改查例子
有关Struts2+Spring+Hibernate和Struts2+Spring+Ibatis的整合实例demo 原创,完全基于eclipse开发
struts+spring+ibatis的Demo struts+spring+ibatis的Demo struts+spring+ibatis的Demo
struts2+spring+Ibatis框架包
里面有spring+struts2+ibatis整合的jar包,
webwork+spring+ibatis很适合初学者的实例
是不是好东西你们去鉴定,SpringMVC + Spring + ibatis 可以配置多数据源,这个Demo 扩展性极强,就看你们自己如何发挥。
JSF+Spring+Ibatis示例,对学习JAVA企业应用开发有巨大的帮助!
struts2+spring+ibatis+oracle+分页搜索+上传附件实例!完整版!
struts2+spring+ibatis的小demo
spring+ibatis+oracle分页缓存源码
maven3+struts2+spring+ibatis,本来是用maven3+struts2+spring+hibernate但考虑到hibernate在多表级联查询的时候执行效率不高,所以改用性能更好不过sql比较麻烦的的ibatis,本项目只有登录和插入数据,仅供参考: ...
一个简单的struts+spring+ibatis示例的源码,在源码中包含一个简单的分布功能
struts+spring+ibatis框架集成.pdf
struts2+spring+ibatis项目实例
Struts+Spring+Ibatis整合框架搭建配置文档
搭建spring mvc+spring+ibatis所需所有jar包、亲测可用!!
Spring + Ibatis 与mysql集群集成