首页 > 其他分享 >事务未提交和连接未关闭

事务未提交和连接未关闭

时间:2024-01-25 09:13:43浏览次数:19  
标签:事务 提交 连接 线程 关闭 链接 连接池

事务未提交和连接未关闭


背景

最近一个项目出现了应用服务器无法登录的现象.
出现现象后,给出了jstack和应用的log等信息. 

jstack 里面所有的 http的nio 线程都在parked状态. 
然后log里面出现了大量的获取不到链接的提示. 

所以第一反应是因为事务未提交导致的连接池泄露. 
但是后续与同事一起看问题时发现, 并没有未提交的事务. 
所以感觉自己可能对 事务未提交和连接未关闭的场景产生了混淆.

所以想着能够总结一下两种场景, 希望能够学习和提高. 

现象

所有的工作线程都进入 parked的状态:
"http-nio-5200-exec-179" #59186 daemon prio=5 os_prio=0 tid=0x00007f4d941ca800 
nid=0x28e3da waiting on condition [0x00007f4b976f9000]
   java.lang.Thread.State: TIMED_WAITING (parking)

服务器没有压力 CPU/内存都很低

应用服务器的日志显示: 
Failed to obtain JDBC Connection; nested exception is java.sql.SQLTransientConnectionException: 
tenancy-connection01 - Connection is not available, request timed out after 30000ms

数据库显示有大量的正在执行的SQL,并且链接未关闭,能够查询出来.

区别和理解-事务未提交

事务未提交和连接未关闭其实是两个维度的问题. 

事务未提交可能链接已经被关闭了. 
这种问题很有可能是 finally 里面有connection的 dispose或者是close的命令
但是存在有 未被捕获的异常导致 transaction 没有commit/rollback 的情况. 

导致应用线程(大部分为http-nio)返回给连接池管理的数据库链接(hikari后者是durid)里面还存在未提交的事务. 
因为应用已经将connection返回给了 pool , 所以pool认为此connection 可以进行服用. 
然后再给其他申请connection的 thread 时, thread 要commit 事务时就会报错, 因为前面存在未rollback的事务.
导致自己的产品出现异常.  所以这个时候, 就会出现施暴者没有反馈, 但是受害者再惨叫的情况. 

此时需要关注的是 链接关闭时, 如果打开链接的线程堆栈忘记了事务的 commit/rollback 需要记录下来. 
这类错误肯定会导致应用上有人报错, 但是报错的不是施暴者, 提前发现很重要. 可以避免问题爆发. 

区别和理解-链接未关闭

链接未关闭的情况时 事务可能未提交, 也可能已经提交了. 
不管事务有没有提交, 那么就需要足够多的异常操作,将连接池占满,导致应用不可用. 

此时需要关注hikari等的连接数指标. 
如果连接数指标单调递增没有下降的趋势, 并且没有应用反馈存在事务条失败的问题时: 
很有可能出现了链接未关闭的问题

需要注意一般情况下连接未关闭时一个比较缓慢的过程. 并且如果业务操作非常低频率
可能很久也发现不了问题. 

但是当存在一种比较2B的代码时可能瞬间将应用服务器的连接池打满
那就是 for循环或者是递归调用 sql执行, 同事没有关闭数据库链接. 
比如连接池设置为100 , 然后一个大于100 的循环内打开链接进行insert 或者是update
并且链接不关闭.  那么很快应用机会不可用,出现宕机的情况. 

防范方法

1. 可以通过代码的规范化检查来避免此类问题. 
2. 通过代码规范, 避免手工建立连接,并且不进行释放来处理. 
3. 测试时需要考虑足够多的场景, 尤其是数据量, 避免小数据量的情况无法发现问题.
4. 必须增加监控指标, 避免测试环境经常重启导致问题外泄. 
5. 举一反三,增加研发培训, 对新员工增加严重问题代码的培训和宣贯.

其他理解

java运行其实是通过jvm虚拟机来进行处理的. 
jvm其实可以理解为一个小型的linux系统. 
既然是虚拟机, 是操作系统, 那么资源就是系统最重要的资产. 
关闭资源就是系统最重要的工作. 

CPU/内存/线程/文件句柄/链接(http,db) 都是系统中的资源.
任何一种资源受到过量的使用都会像癌症一样蔓延到其他的资源.
最终导致系统不可用. 

解决问题的核心其实在于找到那种资源收到了过量的使用. 
并且找到过量使用的始作俑者. 

经历过问题锤炼, 并且有足够的记忆力和敏感度就非常重要了.
遇到问题需要做有根据的假设,并且进行求证. 
但是不能无条件无理由的假设, 调查时的错误假设会导致调查失败.  
调查失败会导致产品不可用, 影响很坏. 

标签:事务,提交,连接,线程,关闭,链接,连接池
From: https://www.cnblogs.com/jinanxiaolaohu/p/17986271

相关文章

  • odbc客户端连接到服务器
    让我们看一个示例代码client1.c。第一个客户端应用程序连接到数据库,然后退出。#include<sql.h>#include<sqlext.h>#include<stdio.h>#include<stdlib.h>intmain(intargc,char*argv[]){ SQLRETURNresult; SQLHENVhenv; SQLHDBChdbc; //1.申请......
  • SpringBoot开启动态定时任务并手动、自动关闭
    场景需求:在执行某个方法的两小时之后进行某个操作涉及:定时任务、哈希表需要注意:业务逻辑层是单一实例的,所以在定时任务类内操作业务逻辑层的某个属性和在业务逻辑层内操作的都是同一个。疑问:ThreadPoolTaskScheduler线程池需不需要规定线程数量?定时任务类@Componentpublicc......
  • Net Core中使用EF Core连接Mysql数据库
    EntityFrameworkCore的前身是微软提供并主推的ORM框架,简称EF,其底层是对ADO.NET的封装。EF支持SQLServer、MYSQL、Oracle、Sqlite等所有主流数据库。首先是使用时的几个模式的整理及其理解:CodeFirst:根据代码自动创建数据库表结构甚至是数据库,可以支持多库开发,代码较少冗余,由......
  • Git提交代码注释规范
    feat(新功能):新增代码文件:新功能相关的代码文件、模块等。更新测试文件:添加新功能的测试用例。fix(修复):修改代码文件:包含有问题代码的文件。更新测试文件:修复问题的测试用例。docs(文档):Markdown文件:更新项目文档、README、帮助文件等。注释:更新代码中的注释,提供更详......
  • Spark Streaming程序优雅关闭
    流式任务需要7*24小时执行,但是有时涉及到升级代码需要主动停止程序,但是分布式程序,没办法做到一个个进程去杀死,所有配置优雅的关闭就显得至关重要了。使用外部文件系统来控制内部程序关闭。其实就是单独起一个线程专门去专门查找程序是否停止的标志importjava.net.URIimport......
  • Ubuntu20.04安装后,root账户无法登录,ssh无法远程连接处理方法
    摘自:https://blog.csdn.net/Alex_81D/article/details/131512358 二、给root账户设置密码,并保证可成功登录1.设置root用户密码在桌面上使用快捷键Ctrl+Alt+T打开终端模拟器执行sudopasswdroot,然后输入设置的密码,输入两次,完成了设置root用户密码2.修改配置文件修改gdm-auto......
  • Java21 + SpringBoot3整合Redis,使用Lettuce连接池,推荐连接池参数配置,封装Redis操作
    目录前言相关技术简介Redis实现步骤引入maven依赖修改配置文件定义Redis配置类定义Redis服务类,封装Redis常用操作使用Redis服务类总结前言近日心血来潮想做一个开源项目,目标是做一款可以适配多端、功能完备的模板工程,包含后台管理系统和前台系统,开发者基于此项目进行裁剪和扩展......
  • 硬链接和软连接
    1、硬链接硬连接指通过索引节点号来进行连接。inode是可以对应多个文件名的在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(InodeIndex)。在Linux中,多个文件名指向同一索引节点是存在的。一般这种连接就是硬连接。硬连接的作用是......
  • 服务器上mysql安装 ,以及客户端Navicat连接
    1.官网下载mysql8.0https://dev.mysql.com/downloads/installer/ 2.安装mysql8.0参考https://blog.csdn.net/weixin_47406082/article/details/131867849?ops_request_misc=&request_id=&biz_id=102&utm_term=mysql%E6%9C%80%E6%96%B0%E7%89%88%E5%AE%89%E8%A3%85%E......
  • 关于流的关闭注意事项
    privatevoidreadTheFile()throwsIOException{Pathpath=Paths.get(this.fileName);BufferedReaderreader=Files.newBufferedReader(path,this.charset);//...reader.close();//Noncompliant//...Files.lines("input.txt").forEac......