From 4f532513a19e2fbad1c81e3198ff2ceb3e83c42b Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Fri, 13 Mar 2026 10:25:56 +0100 Subject: [PATCH] Use row lock for lock table. --- .../Locking/SqlServerEFCoreDistributedLockingMechanism.cs | 4 ++-- .../Services/SqlServerDistributedLockingMechanism.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Cms.Persistence.EFCore/Locking/SqlServerEFCoreDistributedLockingMechanism.cs b/src/Umbraco.Cms.Persistence.EFCore/Locking/SqlServerEFCoreDistributedLockingMechanism.cs index 412e653ebdb4..8ab9e58262de 100644 --- a/src/Umbraco.Cms.Persistence.EFCore/Locking/SqlServerEFCoreDistributedLockingMechanism.cs +++ b/src/Umbraco.Cms.Persistence.EFCore/Locking/SqlServerEFCoreDistributedLockingMechanism.cs @@ -157,7 +157,7 @@ private void ObtainReadLock() "A transaction with minimum ReadCommitted isolation level is required."); } - var number = await dbContext.Database.ExecuteScalarAsync($"SET LOCK_TIMEOUT {(int)_timeout.TotalMilliseconds};SELECT value FROM dbo.umbracoLock WITH (REPEATABLEREAD) WHERE id={LockId}"); + var number = await dbContext.Database.ExecuteScalarAsync($"SET LOCK_TIMEOUT {(int)_timeout.TotalMilliseconds};SELECT value FROM dbo.umbracoLock WITH (ROWLOCK, REPEATABLEREAD) WHERE id={LockId}"); if (number == null) { @@ -190,7 +190,7 @@ private void ObtainWriteLock() } #pragma warning disable EF1002 - var rowsAffected = await dbContext.Database.ExecuteSqlRawAsync(@$"SET LOCK_TIMEOUT {(int)_timeout.TotalMilliseconds};UPDATE umbracoLock WITH (REPEATABLEREAD) SET value = (CASE WHEN (value=1) THEN -1 ELSE 1 END) WHERE id={LockId}"); + var rowsAffected = await dbContext.Database.ExecuteSqlRawAsync(@$"SET LOCK_TIMEOUT {(int)_timeout.TotalMilliseconds};UPDATE umbracoLock WITH (ROWLOCK, REPEATABLEREAD) SET value = (CASE WHEN (value=1) THEN -1 ELSE 1 END) WHERE id={LockId}"); #pragma warning restore EF1002 if (rowsAffected == 0) diff --git a/src/Umbraco.Cms.Persistence.SqlServer/Services/SqlServerDistributedLockingMechanism.cs b/src/Umbraco.Cms.Persistence.SqlServer/Services/SqlServerDistributedLockingMechanism.cs index fb0cb9133ed4..a38a7689b5ce 100644 --- a/src/Umbraco.Cms.Persistence.SqlServer/Services/SqlServerDistributedLockingMechanism.cs +++ b/src/Umbraco.Cms.Persistence.SqlServer/Services/SqlServerDistributedLockingMechanism.cs @@ -144,7 +144,7 @@ private void ObtainReadLock() "A transaction with minimum ReadCommitted isolation level is required."); } - const string query = "SELECT value FROM umbracoLock WITH (REPEATABLEREAD) WHERE id=@id"; + const string query = "SELECT value FROM umbracoLock WITH (ROWLOCK, REPEATABLEREAD) WHERE id=@id"; var lockTimeoutQuery = $"SET LOCK_TIMEOUT {_timeout.TotalMilliseconds}"; @@ -180,7 +180,7 @@ private void ObtainWriteLock() } const string query = - @"UPDATE umbracoLock WITH (REPEATABLEREAD) SET value = (CASE WHEN (value=1) THEN -1 ELSE 1 END) WHERE id=@id"; + @"UPDATE umbracoLock WITH (ROWLOCK, REPEATABLEREAD) SET value = (CASE WHEN (value=1) THEN -1 ELSE 1 END) WHERE id=@id"; var lockTimeoutQuery = $"SET LOCK_TIMEOUT {_timeout.TotalMilliseconds}";