因为很多软件逻辑看起来像这样:
DECLARE @IdLocationsToUpdate TABLE (Id BIGINT)
INSERT INTO @IdLocationsToUpdate (Id)
SELECT Id FROM Warehouse.LocationEntity WHERE ..... -- Complex conditions or other inner joins
UPDATE l
Warehouse.LocationEntity l
INNER JOIN @IdLocationsToUpdate lu ON lu.Id = l.Id
-- Plus multiple other updates and logics on that list of Ids
由于缺少快照,我们现在遇到更新问题。这是因为选择并插入表变量的记录可能已被另一个事务更新,并且现在不应执行更新语句,因为其中一些记录不再满足条件。以前,这是通过快照隔离抛出的异常来避免的,该异常不允许对同一记录进行多次更新。你建议做什么?
希望解释足够清楚。预先感谢。
第一个想法是在所有后续更新中重写第一个选择中使用的 WHERE 条件,但这会使代码更长且混乱。因此,我希望找到一种解决方案来消除数据丢失,同时避免重复的代码,或者重新启用快照隔离的方法。
但是您还需要添加
UPDLOCK
提示,否则它不知道您仍然希望修改这些行。
SET XACT_ABORT ON; -- always use this for better error handling and rollback
BEGIN TRAN;
DECLARE @IdLocationsToUpdate TABLE (Id BIGINT PRIMARY KEY); -- ideally add a primary key
INSERT INTO @IdLocationsToUpdate (Id)
SELECT Id
FROM Warehouse.LocationEntity WITH (UPDLOCK)
WHERE ..... -- Complex conditions or other inner joins
UPDATE l
Warehouse.LocationEntity l
INNER JOIN @IdLocationsToUpdate lu ON lu.Id = l.Id
COMMIT;