- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在 SQL Server 2005 上遇到了多个死锁的问题。该语句位于 INSERT 和 SELECT 语句之间。
有两个表。表1和表2。 Table2 将 Table1 的 PK (table1_id) 作为外键。
table1_id 上的索引是聚集的。
INSERT 一次将一行插入到 table2 中。
SELCET 连接两个表。 (这是一个很长的查询,可能需要长达 12 秒才能运行)
根据我的理解(和实验),INSERT 应该获取 table1 上的 IS 锁来检查引用完整性(这不应导致死锁)。但是,在这种情况下,它获取了 IX 页面锁
死锁报告:
<deadlock-list>
<deadlock victim="process968898">
<process-list>
<process id="process8db1f8" taskpriority="0" logused="2424" waitresource="OBJECT: 5:789577851:0 " waittime="12390" ownerId="61831512" transactionname="user_transaction" lasttranstarted="2010-04-16T07:10:13.347" XDES="0x222a8250" lockMode="IX" schedulerid="1" kpid="3764" status="suspended" spid="52" sbid="0" ecid="0" priority="0" transcount="2" lastbatchstarted="2010-04-16T07:10:13.350" lastbatchcompleted="2010-04-16T07:10:13.347" clientapp=".Net SqlClient Data Provider" hostname="VIDEV01-B-ME" hostpid="3040" loginname="DatabaseName" isolationlevel="read uncommitted (1)" xactid="61831512" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="DatabaseName.dbo.prcTable2_Insert" line="18" stmtstart="576" stmtend="1148" sqlhandle="0x0300050079e62d06e9307f000b9d00000100000000000000">
INSERT INTO dbo.Table2
(
f1,
table1_id,
f2
)
VALUES
(
@p1,
@p_DocumentVersionID,
@p1
) </frame>
</executionStack>
<inputbuf>
Proc [Database Id = 5 Object Id = 103671417] </inputbuf>
</process>
<process id="process968898" taskpriority="0" logused="0" waitresource="PAGE: 5:1:46510" waittime="7625" ownerId="61831406" transactionname="INSERT" lasttranstarted="2010-04-16T07:10:12.717" XDES="0x418ec00" lockMode="S" schedulerid="2" kpid="1724" status="suspended" spid="53" sbid="0" ecid="0" priority="0" transcount="2" lastbatchstarted="2010-04-16T07:10:12.713" lastbatchcompleted="2010-04-16T07:10:12.713" clientapp=".Net SqlClient Data Provider" hostname="VIDEV01-B-ME" hostpid="3040" loginname="DatabaseName" isolationlevel="read committed (2)" xactid="61831406" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="DatabaseName.dbo.prcGetList" line="64" stmtstart="3548" stmtend="11570" sqlhandle="0x03000500dbcec17e8d267f000b9d00000100000000000000">
<!-- XXXXXXXXXXXXXX...SELECT STATEMENT WITH Multiple joins including both Table2 table 1 and .... XXXXXXXXXXXXXXX -->
</frame>
</executionStack>
<inputbuf>
Proc [Database Id = 5 Object Id = 2126630619] </inputbuf>
</process>
</process-list>
<resource-list>
<pagelock fileid="1" pageid="46510" dbid="5" objectname="DatabaseName.dbo.table1" id="lock6236bc0" mode="IX" associatedObjectId="72057594042908672">
<owner-list>
<owner id="process8db1f8" mode="IX"/>
</owner-list>
<waiter-list>
<waiter id="process968898" mode="S" requestType="wait"/>
</waiter-list>
</pagelock>
<objectlock lockPartition="0" objid="789577851" subresource="FULL" dbid="5" objectname="DatabaseName.dbo.Table2" id="lock970a240" mode="S" associatedObjectId="789577851">
<owner-list>
<owner id="process968898" mode="S"/>
</owner-list>
<waiter-list>
<waiter id="process8db1f8" mode="IX" requestType="wait"/>
</waiter-list>
</objectlock>
</resource-list>
</deadlock>
</deadlock-list>
任何人都可以解释为什么 INSERT 会获得 IX 页面锁定吗?
我是否没有正确阅读死锁报告?
顺便说一句,我还没有成功重现这个问题。
谢谢!
编辑:表创建:
CREATE TABLE [dbo].[Table2] (
[Table2_id] [int] IDENTITY (1, 1) NOT NULL ,
[f1] [int] NULL ,
[Table1_id] [int] NOT NULL ,
[f2] [int] NOT NULL ,
)
ALTER TABLE [dbo].[Table2] ADD
CONSTRAINT [FK_Table2_Table1] FOREIGN KEY
(
[Table1_id]
) REFERENCES [dbo].[Table1] (
[Table1_id]
)
CREATE TABLE [dbo].[Table1] (
[Table1_id] [int] IDENTITY (1, 1) NOT NULL ,
)
ALTER TABLE [dbo].[Table1] WITH NOCHECK ADD
CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED
(
[Table1_id]
)
最佳答案
I 表示“意图”锁,它们始终与层次结构相关联。由于锁管理器不了解物理结构,因此他不可能遵守分层锁,因此在意向锁中重新创建了分层结构。
在您的情况下,INSERT 在页面上有一个意向锁。这意味着它还获得了页面中某行的 X 锁,这是正常行为。它现在尝试获取新的 IX 锁,因此它可能需要在不同的页面中插入一行。这是插入具有多个索引的表的正常行为:第一个 IX 位于其中一个索引(可能是聚集索引)上,第二个 IX 位于非聚集索引上。
你说的SELECT在12秒内返回,所以它是一个长查询,在一个大数据集上,并且该计划可能选择了高锁定粒度,页锁。 SELECT 在 INSERT 想要 IX 锁的页面上有一个 S 锁,并且在 INSERT 有 IX 锁的页面上想要另一个 S 锁。
这是一个微不足道的死锁,应该很容易修复它:确保您的 SELECT 不需要这些页面 S 锁。这不是 INSERT 错误。不知道 SELECTt 的作用我无法确定是否是最佳的。根据我的经验,像这样的 SELECT 几乎总是有很多很多的改进空间(无论是 SELECT 本身还是它下面的架构)。
但是承认 SELECT 是最佳选择,最简单的出狱卡就是打开 row versioning :
ALTER DATABASE <dbname> SET ALLOW_SNAPSHOT_ISOLATION ON;
ALTER DATABASE <dbname> SET READ_COMMITTED_SNAPSHOT ON;
更新:
实际上,在第二次读取时,很明显 INSERT 已锁定不同的表(除非您修改了 XML,它看起来到处都是手工编辑的),因此您对插入行为的解释必须错误。 INSERT 是至少两次写入的事务的一部分,一次写入表 1,一次写入表 2。但这并没有改变问题或解决方案。确实,您可以将事务中的两个写入拆分为单独的事务,但这显然是最糟糕的途径。
关于SQL Server INSERT 和 SELECT 语句之间出现死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2735227/
创建一个“海盗对话”,可以选择左手或右手。我希望它对“左”和“右”的不同拼写做出积极的回答(正如您将在代码中看到的那样),但是,当我为所有非“右”或“左”的输入添加最终的“else”代码时,它给了我一
With 语句 对一个对象执行一系列的语句。 With object statements End With 参数 object 必需的部分
While...Wend 语句 当指定的条件为 True 时,执行一系列的语句。 While condition  ; Version [stat
所以我正在处理的代码有一个小问题。 while True: r = input("Line: ") n = r.split() if r == " ":
我有一个对象数组: var contacts = [ { "firstName": "Akira", "lastName": "Laine", "number"
int main() { int f=fun(); ... } int fun() { return 1; return 2; } 在上面的程序中,当从main函数中调用一个
我的项目中有很多 if 语句、嵌套 if 语句和 if-else 语句,我正在考虑将它们更改为 switch 语句。其中一些将具有嵌套的 switch 语句。我知道就编译而言,switch 语句通常更
Rem 语句 包含程序中的解释性注释。 Rem comment 或 ' comment comment 参数是需要包含的注释文本。在 Rem 关键字和 comment 之间应有一个空格。
ReDim 语句 在过程级中声明动态数组变量并分配或重新分配存储空间。 ReDim [Preserve] varname(subscripts) [, varname(subscripts)]
Randomize 语句 初始化随机数生成器。 Randomize [number] number 参数可以是任何有效的数值表达式。 说明 Randomize 使用 number 参数初始
Public 语句 定义公有变量并分配存储空间。在 Class 块中定义私有变量。 Public varname[([subscripts])][, varname[([subscripts])
Sub 语句 声明 Sub 过程的名称、参数以及构成其主体的代码。 [Public [Default]| Private] Sub name [( arglist )]
Set 语句 将对象引用赋给一个variable或property,或者将对象引用与事件关联。 Set objectvar = {objectexpression | New classname
我有这个代码块,有时第一个 if 语句先运行,有时第二个 if 语句先运行。我不确定为什么会这样,因为我认为 javascript 是同步的。 for (let i = 0; i < dataObje
这是一个 javascript 代码,我想把它写成这样:如果此人回答是,则回复“那很酷”,如果此人回答否,则回复“我会让你开心”,如果此人回答的问题包含"is"或“否”,请说“仅键入”是或否,没有任何
这是我的任务,我尝试仅使用简短的 if 语句来完成此任务,我得到的唯一错误是使用“(0.5<=ratio<2 )”,除此之外,构造正确吗? Scanner scn = new Scanner(
有没有办法在 select 语句中使用 if 语句? 我不能在这个中使用 Case 语句。实际上我正在使用 iReport 并且我有一个参数。我想要做的是,如果用户没有输入某个参数,它将选择所有实例。
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: If vs. Switch Speed 我将以 C++ 为例,但我要问的问题不是针对特定语言的。我的意思是一
Property Set 语句 在 Class 块中,声明名称、参数和代码,这些构成了将引用设置到对象的 Property 过程的主体。 [Public | Private] Pro
Property Let 语句 在 Class 块中,声明名称、参数和代码等,它们构成了赋值(设置)的 Property 过程的主体。 [Public | Private] Prop
我是一名优秀的程序员,十分优秀!