Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
ASP.NET Core's SqlDistributedCache exhibits problematic behavior within database transactions. The background process, ScanForExpiredItemsIfRequired, responsible for removing expired cache entries, can execute after the transaction commits. This results in errors due to SQL Server's limitation of concurrent data source access following transaction completion.
The cause is the independent execution of ScanForExpiredItemsIfRequired relative to user transactions. Triggered post-cache read/write, and subject to ExpiredItemsDeletionInterval, it initiates cleanup on a background thread, disconnecting it from the transaction's lifecycle.
This lack of transactional awareness yields problems. The background thread's attempt to delete expired cache rows post-commit can generate random errors. SQL Server may throw exceptions due to an invalid context. Contention can also arise between cleanup and application code; concurrent operations result in resource conflicts. SQL Server's concurrency mechanisms may block or throw errors, impacting performance.
Expected Behavior
Here's how the SqlDistributedCache should behave:
-
Transaction Isolation: The background cleanup of expired items must operate independently of any active database transactions. It should not attempt to use the same database context as a transaction that has already been committed.
-
Dedicated Resources: The cleanup process should use its own dedicated database connection and, if necessary, its own transaction. This ensures it doesn't interfere with the main application's database operations.
-
Preventing Contention: The design must prevent the cleanup process from causing locking or blocking that could impact the application's read and write operations on the cache.
-
Error Prevention: The ScanForExpiredItemsIfRequired method should be modified to avoid attempting to delete expired items within a committed transaction's context, eliminating the current SQL Server errors.
Essentially, the cleanup needs to be a self-contained operation, completely separate from the application's transactional flow.
Steps To Reproduce
No response
Exceptions (if any)
No response
.NET Version
No response
Anything else?
No response