我有一个综合测试,它重现了我们在生产环境中遇到的一些错误。这是重现它的 2 个脚本:
第一
DBCC TRACEOFF(-1,3604,1200) WITH NO_INFOMSGS;
SET NOCOUNT ON;
IF @@TRANCOUNT > 0 ROLLBACK
IF object_id('test') IS NOT NULL
DROP TABLE test
IF object_id('TMP_test') IS NOT NULL
DROP TABLE TMP_test
IF object_id('test1') IS NOT NULL
DROP TABLE test1
CREATE TABLE test(Id INT IDENTITY PRIMARY KEY)
GO
INSERT test DEFAULT VALUES
GO 2000
WHILE 1 = 1
BEGIN
CREATE TABLE TMP_test(Id INT PRIMARY KEY)
INSERT TMP_test SELECT * FROM test
WAITFOR DELAY '0:00:00.1'
BEGIN TRAN
EXEC sp_rename 'test', 'test1'
EXEC sp_rename 'TMP_test', 'test'
EXEC sp_rename 'test1', 'TMP_test'
DROP TABLE TMP_test
commit
END
第二名
SET NOCOUNT ON;
DECLARE @c INT
WHILE 1 = 1
BEGIN
SELECT @c = COUNT(*) FROM Test IF @@ERROR <> 0 BREAK
SELECT @c = COUNT(*) FROM Test IF @@ERROR <> 0 BREAK
/* and repeat this 10-20 times more*/
SELECT @c = COUNT(*) FROM Test IF @@ERROR <> 0 BREAK
END
所以,问题是当我在一个会话中运行第一个脚本并让它运行,然后在单独的会话中运行第二个脚本时,我会得到这种类型的错误:
消息 208,级别 16,状态 1,第 13 行对象名称“测试”无效。
问题是 -为什么我会在第一个脚本的循环结束时看到此错误,COMMIT
而如果有ROLLBACK
?
我有一种感觉,它与情况有某种联系,当脚本提交时,仍然有同名的表,test
但它是一个不同的对象,第二个脚本必须重新编译自己。这没关系。但是为什么会出现 missed table 错误呢?AFAIK - 当我在事务中重命名表时 - 它持有 Sch-M 锁到 tran 端?
有人可以回答或指导我阅读我可以深入阅读并理解原因的技术论文吗?