mybatis逻辑连接未关闭
2015-12-23 10:45
253 查看
首先,我用的框架是Struts2+Spring+Mybatis
最近重构了缓冲池,改用了阿里的druid,因为具有统计功能,我发现我的项目只打开数据库链接却不关闭,那肯定是sqlSessionFactory出问题了。
因为之前的代码不是我写的,尝试着关闭sqlSession后还是不管用,干脆直接使用SqlSessionTemplate。
先配置spring
伪代码如下
这里的SqlSessionTemplate不仅是单例的,而且不需要手工新建和关闭SqlSession
为什么mybatis-spring.jar中的SqlSessionTemplate可以被多个dao复用,而且不会造成数据连接泄露呢,并且还可以自动新建和释放数据库连接?官方解答是因为SqlSessionTemplate是线程安全的,也就是确保每个线程使用的sqlSession的唯一并不互相冲突。
首先看了一下mybatis-spring的源码,发现SqlSessionTemplate是通过代理拦截和SqlSessionHolder实现的sqlsession线程安全和自动新建和释放连接的。看构造函数函数中构建代理类,该代理类实现SqlSession接口,定义了方法拦截器,如果调用代理类实例中实现SqlSession接口定义的方法,该调用则被导向SqlSessionInterceptor的invoke方法,这个方法中自动进行了SqlSession的自动请求和释放(如果不被spring托管则自己新建和释放sqlsession,如果被spring管理则使用SqlSessionHolder进行request和relase操作)
以下网址针对SqlSessionTemplate的线程安全特性进行了详细的探究:/article/6578107.html
另外,这里还有一个坑
上面spring配置里有一个参数被我注释掉了
<constructor-arg index="1" value="BATCH" />
它的意思就是defaultExecutorType=BATCH
defaultExecutorType有三个值:SIMPLE
普通返回;REUSE 重复;BATCH
批量更新。
一旦选择了BATCH
属性,那么所有的更新插入操作返回的那个int类型的数值就会是-2147482646,也就是返回值丢失了。
最近重构了缓冲池,改用了阿里的druid,因为具有统计功能,我发现我的项目只打开数据库链接却不关闭,那肯定是sqlSessionFactory出问题了。
因为之前的代码不是我写的,尝试着关闭sqlSession后还是不管用,干脆直接使用SqlSessionTemplate。
先配置spring
<span style="white-space:pre"> </span><!--创建sqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="configLocation" value="classpath:SqlMapConfig.xml" /> <property name="dataSource" ref="dataSource" /> </bean> <!-- sqlSessionTemplate配置(支持批量) --> <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate"> <!-- 参数1: sqlSessionFactory|参数2:ExecutorType --> <constructor-arg index="0" ref="sqlSessionFactory" /> <!-- 开启BATCH批量更新会丢失更新的返回值,导致返回-2147482646 --> <!-- <constructor-arg index="1" value="BATCH" /> --> </bean>
伪代码如下
//注入spring中配置的SqlSessionTemplate对象,单例 @Resource(name="sqlSessionTemplate") public SqlSessionTemplate sqlSessionTemplate; public void saveTestTrans(){ this.sqlSessionTemplate.selectList("testdomain.selectAnySql", "select * from my_blog where id='1'"); }
这里的SqlSessionTemplate不仅是单例的,而且不需要手工新建和关闭SqlSession
为什么mybatis-spring.jar中的SqlSessionTemplate可以被多个dao复用,而且不会造成数据连接泄露呢,并且还可以自动新建和释放数据库连接?官方解答是因为SqlSessionTemplate是线程安全的,也就是确保每个线程使用的sqlSession的唯一并不互相冲突。
首先看了一下mybatis-spring的源码,发现SqlSessionTemplate是通过代理拦截和SqlSessionHolder实现的sqlsession线程安全和自动新建和释放连接的。看构造函数函数中构建代理类,该代理类实现SqlSession接口,定义了方法拦截器,如果调用代理类实例中实现SqlSession接口定义的方法,该调用则被导向SqlSessionInterceptor的invoke方法,这个方法中自动进行了SqlSession的自动请求和释放(如果不被spring托管则自己新建和释放sqlsession,如果被spring管理则使用SqlSessionHolder进行request和relase操作)
以下网址针对SqlSessionTemplate的线程安全特性进行了详细的探究:/article/6578107.html
另外,这里还有一个坑
上面spring配置里有一个参数被我注释掉了
<constructor-arg index="1" value="BATCH" />
它的意思就是defaultExecutorType=BATCH
defaultExecutorType有三个值:SIMPLE
普通返回;REUSE 重复;BATCH
批量更新。
一旦选择了BATCH
属性,那么所有的更新插入操作返回的那个int类型的数值就会是-2147482646,也就是返回值丢失了。
相关文章推荐
- 使用Contacts Contract Content Provider操作通讯录最佳实践
- 【转载】命令大全
- 如何修改TabBarItem的title的字体和颜色
- Cardboard虚拟现实开发初步(四)
- 圣思园java se培训总结(52-)(泛型)
- javascript 得noscript标签
- 我的拉帘广告小结
- [QQ客服在线]的引用
- 验证IP的正则表达式
- 中国又一款隐身战机亮相:绰…
- uboot启动uImage
- 调用百度地图
- 如何解决Ecshop2.7.3脚本部分Power…
- 启程
- Android 中Message,MessageQueue,Looper,Handler详解+实例
- 归并排序
- iOS APNS 极光推送 点击通知栏跳转应用相应页面
- 动态规划、贪心、回溯、分支限界法解0-1背包问题总结
- junit的常用注解
- js浮点数精度问题(js计算中遇到的坑)