我有一个简单的SQL命令,它应该从表中读取所有记录,然后将它们全部删除。因为其他人可能会在特定时刻写这个表,我想锁定表格,以便我确信我删除的所有内容也是我读过的所有内容。
BEGIN TRAN T1;
SELECT LotID FROM fsScannerIOInvalidCachedLots WITH (TABLOCK, HOLDLOCK);
DELETE FROM fsInvalidCachedLots;
COMMIT TRAN T1;
真奇怪的是,这个USED可以工作。它通过测试工作了一段时间,但现在我猜有些东西已经改变了,因为它正在读取所有内容,但它并没有删除任何记录。因此,SQL Server正在激活高CPU使用率,因为当下次执行时需要更长的时间才能执行,我认为这与锁定有关。
知道这里会发生什么吗?我已经尝试了TABLOCK
和TABLOCKX
更新:哦,是的,我忘了提一下,我不能查询那个表,直到下一次读取程序之后。我的意思是,在该语句在代码中执行(并且命令和连接被丢弃)之后,如果我尝试从Management Studio中查询该表,它就会挂起,我认为这意味着它仍然被锁定。但是如果我单步执行调用程序直到我点击下一个数据库连接,那么在第一次读取之后,该表不再被锁定。
答案 0 :(得分:1)
您的SELECT
从名为fsScannerIOInvalidCachedLots
的表中检索数据,但删除的内容来自名为fsInvalidCachedLots
的其他表。
如果在set xact_abort off
中运行此查询,则事务不会因无效表名中的错误而中止。实际上,select @@trancount
会向您显示有活动的交易,select xact_state()
将返回1表示它处于活动状态且未发生错误。
另一方面,使用set xact_abort on
,事务将中止。 select @@trancount
将返回0,select xact_state()
将返回0(无活动事务)。
有关这些内容的详情,请参阅MSDN上的@@trancount和xact_state()。