The DistributedLock.SqlServer package offers distributed locks based on Microsoft SQL Server application locks. For example:
var @lock = new SqlDistributedLock("MyLockName", connectionString);
await using (await @lock.AcquireAsync())
{
// I have the lock
}
- The
SqlDistributedLock
class implements theIDistributedLock
interface. - The
SqlDistributedReaderWriterLock
class implements theIDistributedUpgradeableReaderWriterLock
interface. - The
SqlDistributedSemaphore
class implements theIDistributedSemaphore
interface. - The
SqlDistributedSynchronizationProvider
class implements theIDistributedLockProvider
,IDistributedUpgradeableReaderWriterLockProvider
, andIDistributedSemaphoreProvider
interfaces.
SQL-based locks can be constructed with a connection string, an IDbConnection
, or an IDbTransaction
. When a connection is passed, the lock will be scoped to that connection and when a transaction is passed the lock will be scoped to that transaction. In most cases, using a connectionString
is preferred because it allows for the library to efficiently multiplex connections under the hood and eliminates the risk that the passed-in IDbConnection
/IDbTransaction
gets used in a way that disrupts the locking process. NOTE that since IDbConnection
/IDbTransaction
objects are not thread-safe, lock objects constructed with them can only be used by one thread at a time.
When connecting using a connectionString
, several other tuning options can also be specified.
KeepaliveCadence
configures the frequency at which an innocuous query will be issued on the connection while the lock is being held. The purpose of automatic keepalive is to prevent SQL Azure's aggressive connection governor from killing "idle" lock-holding connections. Defaults to 10 minutes.UseTransaction
scopes the lock to an internally-managed transaction under the hood (otherwise it is connection-scoped). Defaults to FALSE because this mode is not compatible with multiplexing and thus consumes more connections. It can also lead to long-running transactions which can be disruptive on databases using the full recovery model.UseMultiplexing
allows the implementation to re-use connections under the hood to hold multiple locks under certain scenarios, leading to lower resource consumption. This behavior defaults to ON except in the case whereUseTransaction
is set to TRUE since the two are not compatible. You should only manually disableUseMultiplexing
for troubleshooting purposes if you suspect it is causing issues.