数据库连接池和事务
来源:互联网 发布:手机淘宝申诉在哪里 编辑:程序博客网 时间:2024/05/16 18:48
背景
在高并发情况下,最近项目中出现了锁定量问题,可能原因是出库没有加上锁定量,入库没有减去锁定量,这样会导致不能正常的出库和入库。需要从几个方面来考虑
1、 业务过程中加锁存在问题
2、 事务没有正确提交
3、 提交了之前不合理的事务
4、 存在没有使用事务的业务
于是在数据库理论基础上,做了一些测试来推断问题所在。首先需要铺垫两方面内容:修改数据库my.ini文件,指定其连接最大等待时间。
默认设置如下:
需要修改wait_timeout和interactive_timeout。在my.ini中,找到mysqld在其下增加
Wait_timeout=10
Interactive_timeout=10
修改数据库连接池,指定其回收连接最大等待时间。
removeAbandoned="true"
removeAbandonedTimeout="60"
logAbandoned="true"
这样只要两者不相等就可以分别模拟数据库连接关闭和连接池连接关闭情况下事务的执行情况。如下:
数据库连接关闭
用例1
插入test1,插入test2,插入test3,使数据库连接断开在插入test2处并捕获异常,
结论:
异常之后的所有操作都会报错,所有的操作都不能提交到数据库。错误信息如下:
1、com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfullyreceived from the server was 37,281 milliseconds ago. The last packet sent successfully to theserver was 0 milliseconds ago.
atsun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
Caused by: java.net.SocketException: Software caused connection abort: recv failed
atjava.net.SocketInputStream.socketRead0(Native Method)
2、构造preparedStatement
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
atsun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
3、执行
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after statement closed.
4、提交事务
java.sql.SQLException: Connection has already been closed.
atorg.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:117)
atorg.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:99)
用例2
在用例1基础上,获取同一个连接,并提交事务
结论:
无法获取到同一个连接,当连接关闭后会销毁,下一次请求会创建新连接,因此用例1的未提交事务不会因为用例2的提交被重新提交
数据库连接池连接关闭
用例1
插入test1,插入test2,插入test3,使数据库连接池连接断开在插入test2处并捕获异常,
结论:
异常之后的所有操作都会报错,所有的操作都不能提交到数据库。错误信息如下:
1、Connection has been abandonedPooledConnection[com.mysql.jdbc.JDBC4Connection@bc4a53]:java.lang.Exception
atorg.apache.tomcat.jdbc.pool.ConnectionPool.getThreadDump(ConnectionPool.java:1023)
atorg.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:689)
atorg.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:616)
atorg.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:179)
atorg.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:126)
2、执行插入:
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after statement closed.
atsun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
atsun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
atsun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
atjava.lang.reflect.Constructor.newInstance(Constructor.java:513)
3、提交事务
java.sql.SQLException: Connection has already been closed.
atorg.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:117)
atorg.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:99)
atorg.apache.tomcat.jdbc.pool.interceptor.AbstractCreateStatementInterceptor.invoke(AbstractCreateStatementInterceptor.java:71)
atorg.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:99)
atorg.apache.tomcat.jdbc.pool.interceptor.ConnectionState.invoke(ConnectionState.java:140)
atorg.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:99)
atorg.apache.tomcat.jdbc.pool.TrapException.invoke(TrapException.java:41)
atorg.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:99)
atorg.apache.tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.java:58)
at$Proxy4.getAutoCommit(Unknown Source)
atadultadmin.util.db.DbOperation.commitTransaction(DbOperation.java:142)
用例2
在用例1基础上,获取同一个连接,并提交事务
结论:
无法获取到同一个连接,当连接关闭后连接池会丢弃这个连接,下一次请求会创建新连接,因此用例1的未提交事务不会因为用例2的提交而被重新提交
会造成数据异常原因
正常业务,没有显示进行手动回滚
第一次请求:插入test1,当插入test2时返回并且没有提交事务
第二次请求,获取到同一个连接,插入test1,test2,test3,查询数据库发现test1和test2第一次请求的数据被插入
第三次请求,和第一次请求一致
第四次请求,获取不同连接,不会将第三次数据提交到数据库
正常业务,捕获异常后,没有返回
正常业务,没有判断意外,意外发生时没有显示进行手动回滚
没有使用事务
- 数据库连接池和事务
- 事务以及数据库连接池
- MySQL事务和properties数据库连接
- JDBC、事务、数据库连接池、DBUtils
- JavaWeb: 事务与数据库连接池
- 提供数据库连接池 和数据库连接
- JDBC、JDBC框架、数据库事务、数据库连接池
- springmvc(五)集成阿里 druid数据库连接池和事务等配置,集成mybatis
- ssm框架使用druid数据库连接池(带事务配置和session监听)
- ssm框架使用druid数据库连接池(带事务配置和session监听)
- 数据库连接池 DBCP和c3p0数据库连接池
- JNDI和数据库连接池
- Redis 和数据库连接池
- 数据源 和数据库连接池
- 数据库连接池-DBUtils高级 事务+不确定条件查询+分页
- ThreadLocal解决事务线程安全问题(c3p0数据库连接池工具类)
- 事务+事务的四大特性+隔离性的具体分析+数据库连接池
- 线程池 和数据库连接池
- 天天记录 - Android requestLayout源码简单分析
- 常数变易法的原理解释
- Ajax实现二级联动菜单
- IC
- Yii 框架里数据库操作详解-[增加、查询、更新、删除的方法 (2011-10-25 17:01:25)
- 数据库连接池和事务
- jquery validate (jquery 验证的三种方式)
- 借助FireBug来学习JavaScript的window对象
- UVa10048 Audiophobia (Floyd)
- 一起学java 3
- yarn historyserver 使用解析
- AWK使用总结(5)使用AWK判断是否为中文字符
- 保存一些下载地址
- 谈ui文件的用法