ITPub博客

首页 > 数据库 > SQL Server > 为什么sleeping的会话会造成阻塞

为什么sleeping的会话会造成阻塞

原创 SQL Server 作者:z_cloud_for_SQL 时间:2023-01-19 20:03:43 0 删除 编辑
背景

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

现象 1

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

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


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


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


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

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




分析 2

通过回溯,很容易分析阻塞的原因,首先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更改的数据行的排他锁,其他会话在对表 m z_charge_de tail进行更新时就会被一直阻塞 。

3

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


自动查杀会话 4

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


北京格瑞趋势科技有限公司是聚焦于数据服务的高新技术企业,成立于2008年,创始团队及核心技术人员来自微软和雅虎。微软数据平台金牌合作伙伴,卫宁健康数据平台战略合作伙伴。通过产品+服务双轮驱动的业务模式,14年间累计服务4000+客户,覆盖互联网、市政、交通、电信、医疗、教育、电力、制造业等各个领域。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70023658/viewspace-2932898/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: 论索引的重要性
请登录后发表评论 登录
全部评论
数据库技术运营,多年IT行业从业经验。

注册时间:2022-11-02

  • 博文量
    55
  • 访问量
    61924