示例#1
0
        public EfDistributedLock(Func <AggregateDbContext> contextFactory, EfDistributedLockRecord record, TimeSpan expiration, Action expirationAction = null)
        {
            Guard.ArgumentNotNull(contextFactory, nameof(contextFactory));
            Guard.ArgumentNotNull(record, nameof(record));
            Guard.ArgumentNotNull(expiration, nameof(expiration));

            _action         = expirationAction;
            _contextFactory = contextFactory;
            Expiry          = expiration;
            ExpirationTime  = record.LockDateTime;
            IsAcquired      = record.IsAcquired();
            LockName        = record.Name;
            LockId          = record.LockId;
            var extendTime = (expiration.TotalMilliseconds * 0.9).Do(Convert.ToInt32);

            _timer = new PeriodicAction(ct => ExtendLockAsync(ct), extendTime, null, true);
            _timer.Start();
        }
示例#2
0
        private async Task <EfDistributedLock> TryAquireLock(string name, TimeSpan expiry, Action expirationAction = null)
        {
            _logger.StartAcquireLock(name, expiry);
            try
            {
                using (var context = _dbContextFactory())
                {
                    var dlock = await context.DistributedLocks.SingleOrDefaultAsync(l => l.Name == name);

                    if (dlock == null)
                    {
                        dlock = new EfDistributedLockRecord(name, expiry, Guid.NewGuid());
                        context.DistributedLocks.Add(dlock);
                        dlock.Acquire(expiry);
                        var updated = await context.SaveChangesAsync();

                        if (updated > 0)
                        {
                            _logger.LockIsAcquired(name, expiry);
                            return(new EfDistributedLock(_dbContextFactory, dlock, expiry, expirationAction));
                        }
                    }
                    if (!dlock.IsAcquired())
                    {
                        dlock.Acquire(expiry);
                        var updated = await context.SaveChangesAsync();

                        if (updated > 0)
                        {
                            _logger.LockIsAcquired(name, expiry);
                            return(new EfDistributedLock(_dbContextFactory, dlock, expiry, expirationAction));
                        }
                    }
                }
            }
            catch (DbUpdateConcurrencyException ex)
            {
                _logger.TraceVerboseEvent($"Distributed Lock {name} was not captured due to concurency exception. Exception Message was : {ex.Message}");
            }
            _logger.LockIsNotAcquired(name, expiry);
            return(null);
        }