由事务隔离级别分隔的并发进程死锁

     2023-03-23     251

关键词:

【中文标题】由事务隔离级别分隔的并发进程死锁【英文标题】:deadlock on concurrent processes separated by transaction isolation level 【发布时间】:2011-08-23 13:36:05 【问题描述】:

我们有一个工单表。服务器代理作业从游标中的该表中获取 100 个条目并执行一些工作。为了并行化,有 10 个服务器代理作业,它们调用以下过程(每个都有自己的@process_id):

CREATE PROCEDURE sp_do_workorder @process_id INT
AS
BEGIN TRY
    DECLARE @wo_id NCHAR(40),
        @wo_action NVARCHAR(100),
        @created_at DATETIME,
        @source_proc_name NVARCHAR(100),

    UPDATE procedure_ctrl SET [status]='running' WHERE [procedure]='sp_do_workorder_'+CAST(@process_id AS NVARCHAR(100)) AND [status]='idle'

    WHILE 1=1
    BEGIN
        IF NOT EXISTS (SELECT * FROM procedure_ctrl WHERE [procedure]='sp_do_workorder_'+CAST(@process_id AS NVARCHAR(100)) AND [status]='running') BREAK

        SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
        BEGIN TRANSACTION
            UPDATE workorder SET hash=CAST(@process_id AS NVARCHAR(100))
            FROM workorder x
            INNER JOIN (
                SELECT TOP 100 id FROM workorder WHERE hash='' AND workorder_step=0 ORDER BY created_at ASC
            ) y ON x.id=y.id
        COMMIT TRANSACTION
        SET TRANSACTION ISOLATION LEVEL READ COMMITTED

        DECLARE wo_cur CURSOR FAST_FORWARD FOR SELECT id,action,created_at,optin_source FROM workorder WHERE hash=CAST(@process_id AS NVARCHAR(100)) AND workorder_step=0 ORDER BY created_at ASC
        OPEN wo_cur
        FETCH NEXT FROM wo_cur INTO @wo_id,@wo_action,@created_at,@source_proc_name
        WHILE @@FETCH_STATUS=0
        BEGIN
            EXEC sp_basisprozess @wo_id,@wo_action,@created_at,@source_proc_name,@process_id
            FETCH NEXT FROM wo_cur INTO @wo_id,@wo_action,@created_at,@source_proc_name
        END
        CLOSE wo_cur
        DEALLOCATE wo_cur

        WAITFOR DELAY '00:00:01'
    END

    UPDATE procedure_ctrl SET [status]='idle' WHERE [procedure]='sp_do_workorder_'+CAST(@process_id AS NVARCHAR(100)) AND [status]='running'
END TRY
BEGIN CATCH
    EXEC dbo.sp_listerror
    DECLARE @error NVARCHAR(4000)
    SET @error='[sp_do_workorder]_'+CAST(@process_id AS NVARCHAR(100))+': critical problem'
    RAISERROR(@error, 12, 1)    
END CATCH

对于这 10 个代理工作中的大多数,我们确实经常陷入僵局。有没有人暗示为什么会这样?为了防止副作用,我们使用序列化事务隔离级别,因此只有一个代理作业可以获取一个工作订单条目。如果不设置事务隔离,即使死锁消失了,但通常会发生两个(或更多)代理作业获取相同的工作订单条目。

【问题讨论】:

见Using tables as Queues 听起来不错!我会试一试(稍后再提供反馈) 这似乎完全符合我们的需求,非常棒。请回复您的评论。 【参考方案1】:

我没有尝试具体弄清楚为什么会在您的情况下发生死锁,但似乎您正在有效地使用表作为队列,在这种情况下,请参阅this linked article 了解使用OUTPUT 的方法子句和锁定提示,以最大限度地提高并发性而不会出现死锁。

【讨论】:

事务的特性和隔离级别

事务的特性:ACID原子性:事务是一个不可分割的工作单元,事务中的操作要么都发生,要么都不发生。一致性:一个事务中,事务前后的数据完整性要保持一致。隔离性:多个事务,多个用户并发访问数据库时,一个用户的事... 查看详情

SQL Server 死锁与事务隔离级别读取未提交

】SQLServer死锁与事务隔离级别读取未提交【英文标题】:SQLServerDeadlockwithTransactionIsolationLevelReadUncommitted【发布时间】:2015-04-1520:31:11【问题描述】:即使我将事务级别设置为未提交,我也会遇到这种死锁。有什么我做错了吗?... 查看详情

弱隔离级别&事务并发问题

介绍弱隔离级别为什么要有弱隔离级别如果两个事务操作的是不同的数据,即不存在数据依赖关系,则它们可以安全地并行执行。但是当出现某个事务修改数据而另一个事务同时要读取该数据,或者两个事务同时修改相同数据时... 查看详情

嵌套事务(而不是并发事务)的默认隔离级别是多少?

】嵌套事务(而不是并发事务)的默认隔离级别是多少?【英文标题】:Whatisthedefaultisolationlevelacrossnestedtransactions(insteadofconcurrentones)?【发布时间】:2019-04-2414:14:01【问题描述】:Spring有3种典型的嵌套事务传播:REQUIRED、NEW和NEST... 查看详情

第31讲:mysql事务的并发问题以及事务的隔离级别

文章目录1.事务的并发问题1.1.事务并发之脏读1.2.事务并发之不可重复读1.3.事务并发之幻读2.事务的隔离级别3.模拟事务并发问题的产生以及如何避免3.1.事务并发问题脏读的模拟以及避免3.1.1.模拟事务并发脏读的问题3.1.2.解决事... 查看详情

事务的隔离级别和传播行为

一、什么是事务隔离  一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。 五个事务隔级别:lsolation的属性值1,default默认的事... 查看详情

事务-并发事务演示及隔离级别

   --查看事务隔离级别select@@transaction_isolation;--设置事务隔离级别setsessiontransactionisolationlevelrepeatableread; 查看详情

事务并发之隔离级别

事务事务是作为单个逻辑工作单元执行的一系列操作。一个逻辑工作单元必须有四个属性,称为原子性、一致性、隔离性和持久性(ACID)属性,只有这样才能成为一个事务。事务并发数据库是多个用户(事务)共享的,当多个用户同... 查看详情

通过故意设计+高度并发的事务来最小化死锁?

】通过故意设计+高度并发的事务来最小化死锁?【英文标题】:Minimizingdeadlockswithpurposelycontrived+highlyconcurrenttransactions?【发布时间】:2011-03-2520:54:46【问题描述】:我目前正在对SQLServer2008中的不同隔离级别进行基准测试——但... 查看详情

mysql事务和隔离级别

MySQL事务和隔离级别连接管理器: 接受请求 创建线程 认证用户 建立安全连接 并发控制: 最简单机制是使用锁 多版本并发控制:MVCC(使用其他机制)锁: 读锁:共享锁 写锁:独占锁 加锁: LOCKTABLEStb_name{READ|WRITE}; 解锁: UNL... 查看详情

事务并发事务隔离级别

  不可重复读(NonrepeatableRead) 一个事务的两次读取中,读取相同的资源得到不同的值。当事务T2在事务T1的两次读取之间更新数据,则会发生此种错误(重点在修改) 幻读(Phantom): 此概念相对难理解一些... 查看详情

怎么避免mysql死锁

...ql死锁1、以固定的顺序访问表和行。比如两个更新数据的事务,事务A更新数据的顺序为1,2;事务B更新数据的顺序为2,1;。这样更可能会造成死锁。2、大事务拆小。大事务更倾向于死锁,如果业务允许,将大事务拆小。3.在同... 查看详情

数据库事务4种隔离级别和7种传播行为

  隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为ReadCommitted。它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不... 查看详情

mysql事物及隔离级别(代码片段)

阅读目录一、事务的基本要素(ACID)二、事务的四种隔离级别三、事务的并发问题四、MVCC在MySQL的InnoDB中的实现五MySQL死锁六EXPLAIN分析语句七锁的定义一、事务的基本要素(ACID)1、原子性(Atomicity)࿱... 查看详情

数据库-事务

定义: 数据库事务(DatabaseTransaction),是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性... 查看详情

图解数据库事务的隔离级别(代码片段)

...?我在网上所能找到的答案,帮助个人的理解。答案一:事务隔离级别是并发控制的整体解决方案,其实际上是综合利用各种类型的锁和行版本控制,来解决并发问题。锁是数据库并发控制的内部机制,是基础。对用户来说,只... 查看详情

事务并发传播性隔离级别(代码片段)

事务并发、传播性、隔离级别(重难点)导读:本节重点在于多线程并发环境下的事务处理、和数据库在并发环境下的表锁和行锁。案例:在新增图书的时候,肯定需要先新增作者。SpringMVC声明式事务事务分... 查看详情

mysql逻辑架构事务并发控制(代码片段)

...lMysql逻辑架构连接管理优化与执行并发控制读写锁锁粒度事务隔离级别死锁Mysql中的事务显示的开启事务(InnoDB存储引擎)事务隔离级别在事务中混合使用存储引擎MysqlMysql逻辑架构第一层:负责连接处理、授权认证、... 查看详情