Sql server 2008 如果没有明确定义任何事务,是否会发生死锁?

Sql server 2008 如果没有明确定义任何事务,是否会发生死锁?,sql-server-2008,deadlock,Sql Server 2008,Deadlock,如果我们没有事务块SQL Server 2008 BEGIN TRAN END TRAN 只需删除、更新、插入或选择 有可能出现僵局吗?如果是这样,你能给我举个例子吗?是的,即使没有显式事务,两个不同会话之间也可能发生死锁。下面的示例脚本在我的测试盒上生成死锁 --prep script CREATE TABLE dbo.Example( Col1 int NOT NULL CONSTRAINT PK_Example PRIMARY KEY , Col2 int NOT N

如果我们没有事务块SQL Server 2008

BEGIN TRAN
END TRAN
只需删除、更新、插入或选择


有可能出现僵局吗?如果是这样,你能给我举个例子吗?

是的,即使没有显式事务,两个不同会话之间也可能发生死锁。下面的示例脚本在我的测试盒上生成死锁

--prep script
CREATE TABLE dbo.Example(
      Col1 int NOT NULL CONSTRAINT PK_Example PRIMARY KEY
    , Col2 int NOT NULL
    , Col3 int NOT NULL
    , Col4 char(2000) NULL
    );
GO
WITH 
     t10 AS (SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) t(n))
    ,t1k AS (SELECT 0 AS n FROM t10 AS a CROSS JOIN t10 AS b CROSS JOIN t10 AS c)
    ,t1m AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS num FROM t1k AS a CROSS JOIN t1k AS b CROSS JOIN t1k AS c)
INSERT INTO dbo.Example(Col1, Col2, Col3)
SELECT num, num % 100, num % 150
FROM t1m
WHERE num <= 1000000;
GO

CREATE INDEX idx_Col2 ON dbo.Example(Col2);
CREATE INDEX idx_Col3 ON dbo.Example(Col3);
GO
CHECKPOINT;
DBCC DROPCLEANBUFFERS;
GO

--run this on session 1 after changing time to a near future value
WAITFOR TIME '12:00:00';
UPDATE dbo.Example SET Col3 = 1 WHERE Col2 = 1;
GO

--run this on session 2 after changing time to same time as session 1
WAITFOR TIME '12:00:00';
UPDATE dbo.Example SET Col2 = 2 WHERE Col3 = 1;
GO
我在这个脚本中使用了大量的行,因为它可靠地再现了死锁,即使是在速度很快的机器上。请记住,死锁是一个时间问题,因此我希望可以在慢速框中使用更少的行来重现死锁


即使使用小表、高效查询和自动单语句事务,死锁也是可能的,尽管当查询通过不同的访问路径访问同一资源时,死锁不太可能发生。本例中的查询使用不同的索引,因此不同的锁定顺序可能导致死锁。

是的,即使没有显式事务,两个不同会话之间也可能发生死锁。下面的示例脚本在我的测试盒上生成死锁

--prep script
CREATE TABLE dbo.Example(
      Col1 int NOT NULL CONSTRAINT PK_Example PRIMARY KEY
    , Col2 int NOT NULL
    , Col3 int NOT NULL
    , Col4 char(2000) NULL
    );
GO
WITH 
     t10 AS (SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) t(n))
    ,t1k AS (SELECT 0 AS n FROM t10 AS a CROSS JOIN t10 AS b CROSS JOIN t10 AS c)
    ,t1m AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS num FROM t1k AS a CROSS JOIN t1k AS b CROSS JOIN t1k AS c)
INSERT INTO dbo.Example(Col1, Col2, Col3)
SELECT num, num % 100, num % 150
FROM t1m
WHERE num <= 1000000;
GO

CREATE INDEX idx_Col2 ON dbo.Example(Col2);
CREATE INDEX idx_Col3 ON dbo.Example(Col3);
GO
CHECKPOINT;
DBCC DROPCLEANBUFFERS;
GO

--run this on session 1 after changing time to a near future value
WAITFOR TIME '12:00:00';
UPDATE dbo.Example SET Col3 = 1 WHERE Col2 = 1;
GO

--run this on session 2 after changing time to same time as session 1
WAITFOR TIME '12:00:00';
UPDATE dbo.Example SET Col2 = 2 WHERE Col3 = 1;
GO
我在这个脚本中使用了大量的行,因为它可靠地再现了死锁,即使是在速度很快的机器上。请记住,死锁是一个时间问题,因此我希望可以在慢速框中使用更少的行来重现死锁


即使使用小表、高效查询和自动单语句事务,死锁也是可能的,尽管当查询通过不同的访问路径访问同一资源时,死锁不太可能发生。本例中的查询使用不同的索引,因此不同的锁定顺序可能会导致死锁。

这只适用于1000000,这意味着为了在没有显式事务的情况下发生,我们需要有大量的记录,对吗?@Jamo,您不一定需要一个大表。我在回答中添加了更多细节来解释原因。这只适用于1000000,这意味着为了在没有显式事务的情况下发生,我们需要有大量的记录,对吗?@Jamo,你不一定需要一个大表。我在回答中添加了更多细节来解释原因。