internal void Initialize() { var started = Stopwatch.StartNew(); do { if (SqlUtil.WrapForTransaction(() => SqlUtil.WrapForDeadlock(_cancellationToken, () => { var done = TryLock(() => { var result = false; _storage.UseStatelessSessionInTransaction(session => { var distributedLock = session.Query <_DistributedLock>() .FirstOrDefault(i => i.Resource == _resource); var utcNow = session.Storage.UtcNow; var expireAtAsLong = utcNow.Add(_timeout).ToEpochDate(); if (distributedLock == null) { distributedLock = new _DistributedLock { CreatedAt = utcNow, Resource = _resource, ExpireAtAsLong = expireAtAsLong }; session.Insert(distributedLock); _lockId = distributedLock.Id; result = true; if (Logger.IsDebugEnabled()) { Logger.Debug($"Inserted row for distributed lock '{_resource}'"); } } else if (distributedLock.ExpireAtAsLong < utcNow.ToEpochDate()) { distributedLock.CreatedAt = utcNow; distributedLock.ExpireAtAsLong = expireAtAsLong; session.Update(distributedLock); if (Logger.IsDebugEnabled()) { Logger.Debug($"Re-used row for distributed lock '{_resource}'"); } _lockId = distributedLock.Id; result = true; } }); return(result); }, () => false); return(done); }, _options))) { if (Logger.IsDebugEnabled()) { Logger.DebugFormat("Granted distributed lock '{0}'", _resource); } return; } if (started.Elapsed > _timeout) { break; } if (Logger.IsDebugEnabled()) { Logger.Debug( $"Will poll for distributed lock '{_resource}' in {_options.DistributedLockPollInterval}."); } _cancellationToken.Wait(_options.DistributedLockPollInterval); } while (true); //dont change this. Hangfire looks for resource name in exception properties throw new DistributedLockTimeoutException(_resource); }