我应该使用哪些锁定提示(T
我想要实现如下的原子事务:
BEGIN TRAN A
SELECT id
FROM Inventory
WITH (???)
WHERE material_id = 25 AND quantity > 10
/*
Process some things using the inventory record and
eventually write some updates that are dependent on the fact that
that specific inventory record had sufficient quantity (greater than 10).
*/
COMMIT TRAN A
问题在于还有其他交易正在消耗我们库存中的数量,因此,在记录被选中和更新被写入交易A的时间之间,记录可能变成无效选择,因为它的数量可能已经降低到低于阈值在WHERE子句中。
所以问题是我应该在WITH子句中使用什么锁定提示来防止在完成我的更新和提交事务之前更改选定的库存记录?
编辑:所以,感谢约翰,好的解决方案似乎是将事务隔离级别设置为REPEATABLE READ。 这将确保“在当前事务完成之前,没有其他事务可以修改已被当前事务读取的数据”。
实际上,设置事务隔离级别而不是使用查询提示可能会更好。
以下来自联机丛书的参考资料提供了每个不同隔离级别的详细信息。
http://msdn.microsoft.com/en-us/library/ms173763.aspx
这里有一篇很好的文章解释了SQL Server中各种类型的锁定行为,并提供了一些示例。
http://www.sqlteam.com/article/introduction-to-locking-in-sql-server
表格提示
WITH (HOLDLOCK)
允许其他读者。 正如其他地方所建议的UPDLOCK是独占的。
HOLDLOCK将阻止其他更新,但可能会使用稍后更新的数据。
在您提交或回滚之前,UPDLOCK将阻止任何人读取数据。
你看过sp_getapplock吗? 这将允许您在没有UPDLOCK阻塞的情况下将此代码串行化(如果它是唯一的更新位)
编辑:问题主要在于这个代码在两个不同的会话中运行。 使用HOLDLOCk或REPEATABLE_READ,将在第一次会话更新之前在第二次会话中读取数据。 使用UPDLOCK,任何人都无法读取任何会话中的数据。
MSSQL:
SELECT id
FROM Inventory (UPDLOCK)
WHERE material_id = 25 AND quantity > 10;
http://www.devx.com/tips/Tip/13134
任何你对PostgreSQL感兴趣的机会:
SELECT id
FROM Inventory
WHERE material_id = 25 AND quantity > 10
FOR UPDATE;
链接地址: http://www.djcxy.com/p/32825.html