gpt4 book ai didi

sql - 显示未知索引名称的死锁图

转载 作者:行者123 更新时间:2023-12-03 00:03:16 28 4
gpt4 key购买 nike

我在 SQL Server 2012 中遇到死锁情况。

运行 SQL Server Profiler 后,我得到了如下死锁图:

Deadlock graph

当将鼠标移到进程(椭圆形)上时,两个进程显示相同的PrepareStatement 查询(我正在使用JDBC)。

我使用的查询如下:

MERGE INTO MA4TB_MT_LOG_MSG  USING (VALUES (1)) AS S(Num) ON ( MSG_ID = ? )
WHEN MATCHED THEN
UPDATE SET
DIST_DATE = ?,
DIST_CODE = ?
WHEN NOT MATCHED THEN
INSERT (
MSG_ID, DIST_DATE, DIST_CODE
) VALUES (
?,?,?
);

令我困扰的是Key lock资源框下的索引名称。

我在 MA4TB_MT_LOG_MSG 表下没有名为“1”的索引。

MSG_ID 是 MA4TB_MT_LOG_MSG 的主键,DIST_DATE、DIST_CODE 上没有索引。

关于这种僵局情况的任何形式的建议将不胜感激。

提前致谢,

最佳答案

让我们开始回答您的第一个问题。我没有索引 id = 1。

是的,你知道!!

让我们看一下 SQL Server 2014 CTP2 上的 Adventure Works 2012 数据库。这是我的笔记本电脑规范。

有一个表名称 [AWBuildVersion]。它有一个聚集索引,就像您的表一样。在索引下,我们可以看到 PK 正在显现。如果我们获取表的对象 ID (sys.objects) 并查找索引的条目 (sys.indexes),我们可以看到索引位于位置 1。

简而言之,主键默认是聚集索引。

http://technet.microsoft.com/en-us/library/ms177443(v=sql.105).aspx

enter image description here

好吧,那么没有索引的表有什么呢?这些表称为堆。他们确实在位置 0 处有自己的索引,指向第一个 IAM 页面。

http://technet.microsoft.com/en-us/library/ms188270(v=sql.105).aspx

下面的代码创建一个名为 [crafty] 的架构,并使用 SELECT INTO 将 [AWBuildVersion] 表复制到新架构。 SELECT INTO 的好处是不会保留任何索引。

use AdventureWorks2012
go

create schema [crafty] authorization [dbo];
go

select * into crafty.awbuildversion from dbo.awbuildversion
go

简而言之,我们可以看到在位置 0 处用索引定义的堆。

enter image description here

那么什么是死锁以及请求模式 U 是什么意思?

死锁是指两个进程同时获取资源但顺序不同。简而言之,这两个过程都无法进行。引擎选择回滚时间最少的 session 并终止该进程。

http://technet.microsoft.com/en-us/library/ms178104(v=sql.105).aspx

一图胜千言!事务 1 获取资源 1。事务 2 获取资源 2。当它们尝试获取彼此的资源时,就会产生死锁。

enter image description here

那么按键锁和用户模式U是什么意思呢?

要更新表,您需要更新数据/索引页。但数据页实际上是表中的索引页(聚集索引)。 SQL 引擎取出 (U)PDATE 锁。在实际更新期间,该锁将升级为排它锁(X)。

当两个进程请求独占锁时,可能会出现死锁。

为了完成这个主题,共享锁(SELECT)可以在不阻塞(同时)的情况下执行,通常一个进程开始阻塞,然后当引擎死锁进程线程检测到循环图时变成死锁。

默认隔离级别是未提交读。

http://technet.microsoft.com/en-us/library/ms175519(v=sql.105).aspx

此时,您遇到了僵局。

从这里你要去哪里?

1 - 可能有多个 session (SPID) 运行相同的代码。为什么?您能否更改此设置,以便一次只有一个进程运行该代码?

2 - 获取 JDBC 生成的实际 TSQL。这可以通过 SQL 探查器和/或查看 DMV 来完成。

合并语句执行更新和/或插入操作。因此是一个复合操作。

3 - 能否将隔离级别更改为可序列化?
http://technet.microsoft.com/en-us/library/ms173763.aspx

这将添加更多锁,并且可能会将死锁问题变成超时问题。请参阅 Kalen Daleny 文章了解如何设置 LOCK_TIMEOUT。您必须调整代码才能再次重试该操作,中间有一些延迟。

http://sqlmag.com/sql-server/inside-sql-server-controlling-locking

希望这些信息对您有所帮助。

如果您需要更多帮助,请发布您的 TSQL。

关于sql - 显示未知索引名称的死锁图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18393571/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com