当前位置:网站首页>Could not open JDBC connection for transaction
Could not open JDBC connection for transaction
2022-06-29 09:47:00 【milugloomy】
background
The company recently reported this error in the online project ,Could not open JDBC Connection for transaction, Unable to get the data source connection pool .
analysis
Read the source code , Let's see if the data source connection can be automatically released in all cases .
MyBatis Release the connection
MyBatis Run when running alone SQL Statement will not automatically release the data source connection , But and Spring After consolidation, the data source connection will be automatically released .Spring Changed the MyBatis Of SqlSession, Change to Spring In the integration package SqlSessionTemplate, The key codes are as follows :
public class SqlSessionTemplate implements SqlSession, DisposableBean {
//...
// Omit some code
private class SqlSessionInterceptor implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
SqlSession sqlSession = getSqlSession(
SqlSessionTemplate.this.sqlSessionFactory,
SqlSessionTemplate.this.executorType,
SqlSessionTemplate.this.exceptionTranslator);
try {
Object result = method.invoke(sqlSession, args);
if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
sqlSession.commit(true);
}
return result;
} catch (Throwable t) {
Throwable unwrapped = unwrapThrowable(t);
if (SqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) {
// release the connection to avoid a deadlock if the translator is no loaded. See issue #22
closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
sqlSession = null;
Throwable translated = SqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException) unwrapped);
if (translated != null) {
unwrapped = translated;
}
}
throw unwrapped;
} finally {
if (sqlSession != null) {
closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
}
}
}
}
}
At the end of the finally in , Will close session, Release data source connection .
Business @Transactional Release the connection
Add comments to methods @Transactional Mark the method as a transaction , The connection will also be automatically released , The key codes are as follows :
public class DataSourceTransactionManager extends AbstractPlatformTransactionManager
implements ResourceTransactionManager, InitializingBean {
//...
// Omit some code
@Override
protected void doCleanupAfterCompletion(Object transaction) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
if (txObject.isNewConnectionHolder()) {
TransactionSynchronizationManager.unbindResource(this.dataSource);
}
Connection con = txObject.getConnectionHolder().getConnection();
try {
if (txObject.isMustRestoreAutoCommit()) {
con.setAutoCommit(true);
}
DataSourceUtils.resetConnectionAfterTransaction(con, txObject.getPreviousIsolationLevel());
}
catch (Throwable ex) {
logger.debug("Could not reset JDBC Connection after transaction", ex);
}
if (txObject.isNewConnectionHolder()) {
if (logger.isDebugEnabled()) {
logger.debug("Releasing JDBC Connection [" + con + "] after transaction");
}
DataSourceUtils.releaseConnection(con, this.dataSource);
}
txObject.getConnectionHolder().clear();
}
Among them ,DataSourceUtils.releaseConnection(con, this.dataSource) Method closes the data source connection .
To find problems
The company project uses Druid data source , The maximum number of connections is set to 50, Follow the above analysis , Under normal circumstances, it is impossible to use up , There must be some code that doesn't release the connection .
I've been looking for it for a long time , Finally locate the following code :
@Autowired
private SqlSessionFactory sqlSessionFactory;
public void batchInsert(List<TaskCenter> list) {
if(list == null || list.size() == 0){
return;
}
try {
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
TaskCenterMapper mapper = sqlSession.getMapper(TaskCenterMapper.class);
for(TaskCenter taskCenter : list){
mapper.insertSelective(taskCenter);
}
sqlSession.flushStatements();
sqlSession.commit();
log.info(" Batch insert succeeded : " + list.size()+" Data ");
}catch (Exception ex){
log.error(" Batch insert failed : ", ex);
}
}
This code means to use MyBatis Batch insert function of batch insert data , We analyzed above , Use MyBatis Of SqlSession The data source connection will not be closed automatically , Need to use Spring Packed SqlSessionTemplate Will automatically close the data source connection . So every time you execute this batchInsert Method , Will occupy a data source connection without releasing , Eventually, the data source connection pool is full , Unable to open new connection .
solve the problem
Based on the above analysis , There are two solutions to this problem
1、 Add this method to the transaction , Add a comment to the method @Transactional, The code is as follows :
@Transactional
public void batchInsert(List<TaskCenter> list) {
if(list == null || list.size() == 0){
return;
}
// Omitted below
// ...
2、 Use up sqlSession Manual closing after sqlSession, The code is as follows :
public void batchInsert(List<TaskCenter> list) {
if(list == null || list.size() == 0){
return;
}
SqlSession sqlSession = null;
try {
sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
TaskCenterMapper mapper = sqlSession.getMapper(TaskCenterMapper.class);
for(TaskCenter taskCenter : list){
mapper.insertSelective(taskCenter);
}
sqlSession.flushStatements();
sqlSession.commit();
log.info(" Batch insert succeeded : " + list.size()+" Data ");
}catch (Exception ex){
log.error(" Batch insert failed : ", ex);
}finally {
if (sqlSession != null) {
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
}
}
}
Conclusion
According to a production problem, this article analyzes the source code to understand MyBatis The framework and Spring Transaction management automatically turns off the data source connection pool , Understand the principle to solve the problem .
边栏推荐
- 【华为认证】HCIA-DATACOM史上最全精选题库(附答案解析)
- Pytorch summary learning series - data manipulation
- 爱快安装或重置后,PC或手机端获取不到ip
- es报错NoNodeAvailableException[None of the configured nodes are available:[.127.0.0.1}{127.0.0.1:9300]
- Summary of 3DMAX jamming, white screen and rendering crash
- 股票炒股账号开户安全吗?是靠谱的吗?
- LSM6DSL之SPI驱动
- Construction and use of Changan chain go language smart contract environment
- User level threads and kernel level threads
- Mongodb persistence
猜你喜欢

长安链数据存储介绍及Mysql存储环境搭建

数据治理:数据标准管理(第三篇)

UE4 installs the datasmith plug-in in version 4.20-23

Fabrication d'une calculatrice d'addition simple basée sur pyqt5 et Qt Designer

MySQL configuring master-slave databases

Mongodb persistence
![[Huawei certification] the most complete and selected question bank in hcia-datacom history (with answer analysis)](/img/d4/f5ea847573433f7ca7bd429f57e40a.png)
[Huawei certification] the most complete and selected question bank in hcia-datacom history (with answer analysis)

KiCad学习笔记--快捷键

UE4 编译单个文件(VS与编辑器分别启动)

3DMax 卡死、白屏、渲染死机问题总结
随机推荐
UE4 VS的Visual Assist插件设置
Fabrication d'une calculatrice d'addition simple basée sur pyqt5 et Qt Designer
cenos7下搭建LAMP环境
Automatic Multi-Organ SegmVentation on Abdominal CT With Dense V-Networks
Invalidconnectionattributeexception exception exception handling
Pytorch learning summary - memory cost of operation
UE4 display 3D editable points in Viewport
Mysql配置主从数据库
UE4 动画重定向
长安链数据存储介绍及Mysql存储环境搭建
CROSSFORMER: A VERSATILE VISION TRANSFORMER BASED ON CROSS-SCALE ATTENTION
Es error nonodeavailableexception[none of the configured nodes are available:[.127.0.0.1}{127.0.0.1:9300]
ThinkPHP 6 uses mongodb
Matlab tips (21) matrix analysis -- partial least squares regression
请用已学过的知识编写程序,找出小甲鱼藏在下边这个长字符串中的密码,密码的埋藏点符合以下规律:
[Huawei certification] the most complete and selected question bank in hcia-datacom history (with answer analysis)
A comparison of methods for fully automatic segmentation of tumors and involved nodes in PET/CT of h
Easyexcl export 1million lines of EXECL report font error solution
es报错NoNodeAvailableException[None of the configured nodes are available:[.127.0.0.1}{127.0.0.1:9300]
Recursive RBAC menu level display infinite classification