internal FluentNHibernateDistributedLock Acquire() { var finish = DateTime.Now.Add(_timeout); while (true) { _cancellationToken.ThrowIfCancellationRequested(); if (SqlUtil.WrapForTransaction(() => { lock (Mutex) { using (var session = _storage.GetSession()) { using (var transaction = session.BeginTransaction(IsolationLevel.Serializable)) { var utcNow = session.Storage.UtcNow; var count = session.CreateQuery(SqlUtil.GetCreateDistributedLockStatement()) .SetParameter(SqlUtil.ResourceParameterName, _resource) .SetParameter(SqlUtil.ExpireAtAsLongParameterName, utcNow.Add(_timeout).ToUnixDate()) .SetParameter(SqlUtil.NowParameterName, utcNow) .SetParameter(SqlUtil.NowAsLongParameterName, utcNow.ToUnixDate()); if (count.ExecuteUpdate() > 0) { transaction.Commit(); return(true); } } } } return(false); })) { Logger.DebugFormat("Granted distributed lock for {0}", _resource); _acquired = true; return(this); } if (finish > DateTime.Now) { _cancellationToken.WaitHandle.WaitOne(DelayBetweenPasses); } else { throw new FluentNHibernateDistributedLockException("cannot acquire lock"); } } }
private bool CreateLockRow() { return(SqlUtil.WrapForDeadlock(() => { lock (Mutex) { using (var session = _storage.GetSession()) { using (var transaction = session.BeginTransaction(IsolationLevel.Serializable)) { var lockResourceParams = new LockResourceParams(session, _resource, _timeout); var query = session.CreateQuery(SqlUtil.GetCreateDistributedLockStatement()) .SetParameter(SqlUtil.ResourceParameterName, lockResourceParams.Resource) .SetParameter(SqlUtil.ExpireAtAsLongParameterName, lockResourceParams.ExpireAtAsLong) .SetParameter(SqlUtil.CreatedAtParameterName, lockResourceParams.CreatedAt) .SetParameter(SqlUtil.UtcNowAsLongParameterName, lockResourceParams.CreatedAtAsLong); var count = query.ExecuteUpdate(); if (count == 1) { transaction.Commit(); if (Logger.IsDebugEnabled()) { Logger.DebugFormat("Created distributed lock for {0}", JsonConvert.SerializeObject(lockResourceParams)); } return true; } } } return false; } }, _options)); }