将从内部交易中删除从交易后删除记录
Will delete from inside transaction remove records from after transaction
我有一个简短的问题要问你...如果我 运行 以下命令:
BEGIN TRANSACTION
<commands...>
DELETE FROM <table>
COMMIT TRANSACTION
虽然上面的 t运行saction 是 运行,但在 table 上执行了插入。是否删除:
- 删除 t运行saction 开始后添加的数据
- 仅删除 t运行saction 开始时存在的数据或作为 t运行saction
的一部分添加的数据
希望有人能提供帮助。
我假设您 运行 在一个 SPID 中插入您的代码,并且插入将 运行 在其他 SPID 上并且隔离级别是 SQL 服务器中的默认级别 - 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) 在查询中 window 1
BEGIN TRANSACTION
DELETE FROM dbo.Test where ID > 100000
3) 在查询中 window 2
INSERT INTO Test (Id, Value)
SELECT 100000000 + ROW_NUMBER() OVER (ORDER BY (SELECT 1)), text
from sys.messages
sp_who2 active
显示第二个查询 (SPID) 被第一个查询阻塞,因此查询正在等待获取锁
3) 在查询中 window 1
COMMIT -- query 1 will finish
4) 第二个查询将完成
因此,INSERT 必须等到 DELETE 完成。
- 是的。为什么不?如果您事务中的其他查询不会在 your_table 上持有锁,SQL 服务器将在 DELETE 操作开始后开始使用更新锁锁定 your_table。因此,在此操作之前,所有其他进程都可以成功地将新行添加到 table.
- 在您的案例中,DELETE 将删除所有已提交的数据,这些数据在 DELETE 操作之前存在于您的 table 中。此事务未提交的数据也将被删除。
您需要深入了解锁定和事务隔离级别主题。看看这个例子,它可能比之前的答案更常见。此处未阻止 INSERT,因为 DELETE 只是为 DELETE 操作锁定一组键。
而且无论如何,在 DELETE 操作开始之前,如果此事务中的其他查询未持有此 table 上的锁,SQL 服务器没有理由阻止来自其他事务的 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)
我有一个简短的问题要问你...如果我 运行 以下命令:
BEGIN TRANSACTION
<commands...>
DELETE FROM <table>
COMMIT TRANSACTION
虽然上面的 t运行saction 是 运行,但在 table 上执行了插入。是否删除:
- 删除 t运行saction 开始后添加的数据
- 仅删除 t运行saction 开始时存在的数据或作为 t运行saction 的一部分添加的数据
希望有人能提供帮助。
我假设您 运行 在一个 SPID 中插入您的代码,并且插入将 运行 在其他 SPID 上并且隔离级别是 SQL 服务器中的默认级别 - 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) 在查询中 window 1
BEGIN TRANSACTION
DELETE FROM dbo.Test where ID > 100000
3) 在查询中 window 2
INSERT INTO Test (Id, Value)
SELECT 100000000 + ROW_NUMBER() OVER (ORDER BY (SELECT 1)), text
from sys.messages
sp_who2 active
显示第二个查询 (SPID) 被第一个查询阻塞,因此查询正在等待获取锁
3) 在查询中 window 1
COMMIT -- query 1 will finish
4) 第二个查询将完成
因此,INSERT 必须等到 DELETE 完成。
- 是的。为什么不?如果您事务中的其他查询不会在 your_table 上持有锁,SQL 服务器将在 DELETE 操作开始后开始使用更新锁锁定 your_table。因此,在此操作之前,所有其他进程都可以成功地将新行添加到 table.
- 在您的案例中,DELETE 将删除所有已提交的数据,这些数据在 DELETE 操作之前存在于您的 table 中。此事务未提交的数据也将被删除。
您需要深入了解锁定和事务隔离级别主题。看看这个例子,它可能比之前的答案更常见。此处未阻止 INSERT,因为 DELETE 只是为 DELETE 操作锁定一组键。
而且无论如何,在 DELETE 操作开始之前,如果此事务中的其他查询未持有此 table 上的锁,SQL 服务器没有理由阻止来自其他事务的 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)