背景

客户反映HIS数据库每天22点后都会发生阻塞,阻塞的源头是一个sleeping的会话,越阻塞越多,只能通过手动KILL掉才能解决,十分不解为什么状态为sleeping的会话会造成阻塞。

现象

在SQL专家云的活动会话中,回溯22点一个小时内的运行情况,从22点开始出现阻塞情况。

转到活动会话原始数据,看到ID为2661的会话是阻塞源头,且状态为sleeping。

查看2661的完整信息,发现该会话中有3个打开的事务,一直没有关闭,打开事务的时间为22:00。

再转到22:00的活动会话原始数据,发现会话2661被会话615阻塞。当时2661正在执行到一个存储过程的UPDATE语句。

在慢语句中找到会话2661,执行时间为30秒多一点。向客户证实,程序上设置的SQL语句的超时时间为30秒,说明2661被阻塞导致超时了。

会话615是一个作业,22点开始执行,执行时间91秒。

分析

通过回溯,很容易分析阻塞的原因,首先22:00运行的作业会话615阻塞了会话2661,当时会话2661正在执行的SQL语句为存储过程中的语句update yz_zy_patient。

通过存储过程的定义可以看到,会话2661在被阻塞之前,已经执行完了begin tran和update mz_charge_detail语句。

 

因为会话2661一直被阻塞,直到30秒后超时,所以不会执行到下面的COMMIT语句。最重要的是,应用程序实现的不健壮,语句超时报错后没有进行错误处理,回滚事务并关闭连接(会话),导致会话2661变成了一个“僵尸”会话。因为没有处理事务,会话2661一直持有对表mz_charge_detail更改的数据行的排他锁,其他会话在对表mz_charge_detail进行更新时就会被一直阻塞。

解决

  1. 修改应用程序,增加对执行异常的捕获,回滚事务并关闭连接。这是最根本的解决办法。
  2. 修改存储过程,在事务开始之前增加SET XACT_ABORT ON语句,当 SET XACT_ABORT 为 ON 时,如果 SQL 语句产生运行时错误,整个事务将自动终止并回滚。在修改应用程序之前作为临时解决办法。

自动查杀会话

sleeping会话导致阻塞是一个非常普遍的问题,因为很多客户是购买软件厂商的产品,修改程序的根本解决办法不容易落实。因此只能在数据库端进行补偿性的措施,就是配置一个自动查杀会话的作业,根据这种会话的特征定期KILL掉。也可以在SQL专家云中启用自动查杀会话的功能。

最新文章

  1. 流程开发Activiti 与SpringMVC整合实例
  2. RabbitMQ调试与测试工具-v1.0.1 -提供下载测试与使用
  3. ubuntu中 不同JDK版本之间的切换
  4. asp TreeView控件的使用
  5. Python进阶之“属性(property)”详解
  6. 常用linux命令积累
  7. CPU卡及NFC供应商
  8. java 和javaw 的区别——<转>
  9. (step5.1.6)hdu 1272(小希的迷宫——并查集)
  10. Sqlite ContentProvider Loader 上下文 对话框
  11. gwt CellTable中的控件按Tab键切换
  12. 信息安全的核心:CIA三元组 | 安全千字文系列1
  13. DOS常用命令及进制转换
  14. 数据库操作sql
  15. 结合JDK源码看设计模式——原型模式
  16. densenet 中的shortcut connection
  17. MVC过滤器使用方法
  18. Java:JavaBean和BeanUtils
  19. Python 脚本利用adb 进行手机控制
  20. 盘古分词+一元/二元分词Lucene

热门文章

  1. Hashcat使用指南
  2. i春秋Vld
  3. 【Devexpress】pivotGridControl设置不显示展开折叠按钮
  4. Lakehouse架构指南
  5. 【每日一题】【dfs重载原始函数&循环/函数结束条件&左右下标在数组中位置的确定】2022年2月7日-NC12 由先序和中序遍历重建二叉树
  6. USB口3A限流保护芯片。带短路保护
  7. elasticsearch倒排索引(全面了解)
  8. Python报SyntaxError: Missing parentheses in call to ‘print’. Did you mean print()
  9. 编写异步任务@Async出现bean无法注入的问题解决方案
  10. [编程基础] C++多线程入门1-创建线程的三种不同方式