将从内部事务中删除从事务后删除记录

时间:2015-12-24 12:16:25

标签: sql-server sql-server-2012 transactionscope

我有一个简单的问题...如果我运行以下命令:

BEGIN TRANSACTION
 <commands...>
 DELETE FROM <table>
COMMIT TRANSACTION

当上述事务正在运行时,在表上执行插入操作。请问删除:

  1. 删除交易开始后添加的数据
  2. 仅删除在交易开始时存在的数据或作为交易的一部分添加的数据
  3. 希望有人可以提供帮助。

3 个答案:

答案 0 :(得分:3)

您需要深入了解“锁定和事务隔离级别”主题。看看这个例子,这可能比上一个答案更常见。此处未阻止INSERT,因为DELETE只是锁定了一组DELETE操作的键。

无论如何,在DELETE操作开始之前,如果此事务中的其他查询没有在此表上持有锁,则SQL Server没有理由阻止INSERT操作从其他事务开始。

CREATE TABLE t (Id int PRIMARY KEY)
GO

INSERT INTO t VALUES(1)
GO

BEGIN TRAN

DELETE FROM t

-- separate window
INSERT INTO t VALUES(2)

答案 1 :(得分:2)

我假设您正在一个SPID中运行代码,插件将在其他SPID上运行,隔离级别是SQL SERVER中的默认级别 - READ COMMITTED

很快,答案是否定的,因为INSERT将等待DELETE结束。像这样测试:

1)设置:

-- drop table dbo.Test
CREATE TABLE dbo.Test
(
    Id INT NOT NULL,
    Value NVARCHAR(4000)
)
GO

INSERT INTO Test (Id, Value) 
SELECT  ROW_NUMBER() OVER (ORDER BY (SELECT 1)), text
from sys.messages
GO

2)在查询窗口1中

BEGIN TRANSACTION
DELETE FROM dbo.Test where ID > 100000

3)在查询窗口2中

INSERT INTO Test (Id, Value) 
SELECT 100000000 + ROW_NUMBER() OVER (ORDER BY (SELECT 1)), text
from sys.messages

sp_who2 active显示第一个查询阻止了第二个查询(SPID),因此查询等待获取锁定

3)在查询窗口1中

COMMIT -- query 1 will finish

4)第二次查询将完成

因此,INSERT必须等到DELETE结束。

答案 2 :(得分:0)

  1. 是。为什么不?如果事务中的其他查询不能保存your_table上的锁,则SQL Server将在DELETE操作启动后立即开始使用Update锁锁定your_table。因此,在此操作之前,所有其他进程都可以成功地向表中添加新行。
  2. DELETE在你的情况下将删除所有提交的数据,在DELETE操作之前存在于你的表中。此交易的未提交数据也将被删除。