Skip to content

Commit abeb7cd

Browse files
authored
SqlServerCache: fix thread race condition when multiple threads calling ScanForExpiredItemsIfRequired (dotnet/extensions#3641)
\n\nCommit migrated from dotnet/extensions@2c9e0f1
1 parent 78e9e60 commit abeb7cd

File tree

1 file changed

+8
-5
lines changed

1 file changed

+8
-5
lines changed

src/Caching/SqlServer/src/SqlServerCache.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public class SqlServerCache : IDistributedCache
2525
private DateTimeOffset _lastExpirationScan;
2626
private readonly Action _deleteExpiredCachedItemsDelegate;
2727
private readonly TimeSpan _defaultSlidingExpiration;
28+
private readonly Object _mutex = new Object();
2829

2930
public SqlServerCache(IOptions<SqlServerCacheOptions> options)
3031
{
@@ -227,12 +228,14 @@ public async Task SetAsync(
227228
// If sufficient time has elapsed then a scan is initiated on a background task.
228229
private void ScanForExpiredItemsIfRequired()
229230
{
230-
var utcNow = _systemClock.UtcNow;
231-
// TODO: Multiple threads could trigger this scan which leads to multiple calls to database.
232-
if ((utcNow - _lastExpirationScan) > _expiredItemsDeletionInterval)
231+
lock(_mutex)
233232
{
234-
_lastExpirationScan = utcNow;
235-
Task.Run(_deleteExpiredCachedItemsDelegate);
233+
var utcNow = _systemClock.UtcNow;
234+
if ((utcNow - _lastExpirationScan) > _expiredItemsDeletionInterval)
235+
{
236+
_lastExpirationScan = utcNow;
237+
Task.Run(_deleteExpiredCachedItemsDelegate);
238+
}
236239
}
237240
}
238241

0 commit comments

Comments
 (0)