diff options
| author | Marc Brooks <IDisposable@gmail.com> | 2026-08-06 00:52:34 -0500 |
|---|---|---|
| committer | Marc Brooks <IDisposable@gmail.com> | 2026-08-06 00:52:34 -0500 |
| commit | dd81e52f818295a3ef12880f2be8f24c8c1269c0 (patch) | |
| tree | 04dd2b7839195a0284f94fc755af81d7dff80a1d | |
| parent | cd5962df50ab493cc3739e6a81f66627670b7c8b (diff) | |
Add warning that PessimisticLockBehavior is unsafe
Since it uses ReaderWriterLockSlim, it gets tripped up if the transaction
is continued across an await boundary on a different thread.
| -rw-r--r-- | src/Jellyfin.Database/Jellyfin.Database.Implementations/Locking/PessimisticLockBehavior.cs | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/src/Jellyfin.Database/Jellyfin.Database.Implementations/Locking/PessimisticLockBehavior.cs b/src/Jellyfin.Database/Jellyfin.Database.Implementations/Locking/PessimisticLockBehavior.cs index 404292e8eb..e7a7d5a53f 100644 --- a/src/Jellyfin.Database/Jellyfin.Database.Implementations/Locking/PessimisticLockBehavior.cs +++ b/src/Jellyfin.Database/Jellyfin.Database.Implementations/Locking/PessimisticLockBehavior.cs @@ -17,6 +17,13 @@ namespace Jellyfin.Database.Implementations.Locking; /// <summary> /// A locking behavior that will always block any operation while a write is requested. Mimicks the old SqliteRepository behavior. /// </summary> +/// <remarks> +/// Unsafe with asynchronous transactions; because <see cref="ReaderWriterLockSlim"/> is +/// thread-affine, holding it from <c>TransactionStarting</c> to <c>TransactionCommitted</c> +/// works only while continuations resume inline. A genuinely-async continuation inside a +/// transaction releases on another thread, throwing +/// <see cref="SynchronizationLockException"/> or deadlocking a later write. +/// </remarks> public class PessimisticLockBehavior : IEntityFrameworkCoreLockingBehavior { private readonly ILogger<PessimisticLockBehavior> _logger; @@ -47,7 +54,8 @@ public class PessimisticLockBehavior : IEntityFrameworkCoreLockingBehavior /// <inheritdoc/> public void Initialise(DbContextOptionsBuilder optionsBuilder) { - _logger.LogInformation("The database locking mode has been set to: Pessimistic."); + _logger.LogWarning( + "The database locking mode has been set to: Pessimistic. This mode is not safe with asynchronous transactions and can deadlock."); optionsBuilder.AddInterceptors(new CommandLockingInterceptor(_loggerFactory.CreateLogger<CommandLockingInterceptor>())); optionsBuilder.AddInterceptors(new TransactionLockingInterceptor(_loggerFactory.CreateLogger<TransactionLockingInterceptor>())); } |
