public void AcquireFromMultipleThreads() { var db = RedisUtils.CreateClient(); var sync = new ManualResetEventSlim(); var thread1 = new Thread(state => { using (var testLock1 = RedisLock.Acquire(db, "test", TimeSpan.FromMilliseconds(50))) { // ensure nested lock release doesn't release parent lock using (var testLock2 = RedisLock.Acquire(db, "test", TimeSpan.FromMilliseconds(50))) { } sync.Set(); Thread.Sleep(200); } }); var thread2 = new Thread(state => { Assert.True(sync.Wait(1000)); Assert.Throws <DistributedLockTimeoutException>(() => { using (var testLock2 = RedisLock.Acquire(db, "test", TimeSpan.FromMilliseconds(50))) { } }); }); thread1.Start(); thread2.Start(); thread1.Join(); thread2.Join(); }
public void TwoContendingLocks() { var db = RedisUtils.CreateClient(); using (var testLock1 = new RedisLock(db, "testLock", "owner", TimeSpan.FromMilliseconds(100))) Assert.Throws <TimeoutException>(() => new RedisLock(db, "testLock", "otherOwner", TimeSpan.FromMilliseconds(10))); }
private async Task NestedTask(IDatabase db) { await Task.Yield(); using (var lestLock2 = RedisLock.Acquire(db, "test", TimeSpan.FromMilliseconds(10))) Assert.NotNull(lestLock2); }
public async ValueTask <ILock> GetLock(string key) { if (_disposed) { throw new LockException("LockProvider is disposed"); } StartMonitoring(); var @lock = new RedisLock(key, this); //await _db.sScriptEvaluateAsync(_script, new RedisKey[] { new RedisKey(key) }); var adquired = await _db.LockTakeAsync(key, @lock.Token, _expire); if (adquired) { _logger.LogInformation("Lock on {Key} adquired", @lock.Key); @lock.AdquireLock(); lock (_locks) { _locks.Add(@lock); } return(@lock); } lock (_locks) { _locks.Add(@lock); } _logger.LogInformation("Lock on {Key} pending", @lock.Key); return(await @lock.CreateTask()); }
/// <summary> /// 秒杀方法 /// </summary> public void SkillProduct() { try { RedisLock redisLock = new RedisLock(); redisLock.Lock(); // 1、获取商品库存 var stocks = getPorductStocks(); // 2、判断商品库存是否为空 if (stocks == 0) { // 2.1 秒杀失败消息 Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}:不好意思,秒杀已结束,商品编号:{stocks}"); redisLock.unLock(); return; } // 3、秒杀成功消息 Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}:恭喜你,秒杀成功,商品编号:{stocks}"); // 4、扣减商品库存 subtracPorductStocks(); redisLock.unLock(); } catch (Exception e) { Console.WriteLine(e); } }
public void GetLock_With_Single_Thread_Test() { var rl = new RedisLock(rk, rs, defaultExpire); //test logic:expireDate is too small var r1 = rl.GetLock(); var r2 = rl.GetLock(); Assert.True(r1 && r2); }
public void AcquireAndDisposeLock() { var db = RedisUtils.CreateClient(); using (var testLock = new RedisLock(db, "testLock", "owner", TimeSpan.FromMilliseconds(1))) Assert.NotNull(testLock); using (var testLock = new RedisLock(db, "testLock", "owner", TimeSpan.FromMilliseconds(1))) Assert.NotNull(testLock); }
public RedSyncLock(RedisContextProvider context, string key, int expiryTimeout = 30000, int waitTimeout = 10000, int retryTimeout = 100) { if (context == null) { throw new ArgumentNullException(nameof(context)); } _lock = context.LockFactory.Create(key, TimeSpan.FromMilliseconds(expiryTimeout), TimeSpan.FromMilliseconds(waitTimeout), TimeSpan.FromMilliseconds(retryTimeout)); }
public void AcquireInSequence() { var db = RedisUtils.CreateClient(); using (var testLock = RedisLock.Acquire(db, "testLock", TimeSpan.FromMilliseconds(1))) Assert.NotNull(testLock); using (var testLock = RedisLock.Acquire(db, "testLock", TimeSpan.FromMilliseconds(1))) Assert.NotNull(testLock); }
/// <summary> /// 演示阻塞锁 /// </summary> /// <param name="redisManager"></param> /// <param name="index"></param> /// <returns></returns> private static async Task ShowBlockingLockAsync(RedisManager redisManager, int index) { Console.WriteLine($"{index} Start"); await using RedisLock redisLock = await redisManager.GetBlockingLockAsync("LockKey", 10000); await Task.Delay(1000); Console.WriteLine($"{index} End"); }
public void NestLock() { var db = RedisUtils.CreateClient(); using (var testLock1 = new RedisLock(db, "testLock", "owner", TimeSpan.FromMilliseconds(100))) { using (var testLock2 = new RedisLock(db, "testLock", "owner", TimeSpan.FromMilliseconds(100))) { } } }
public void GetLockAfterAnotherTimeout() { var db = RedisUtils.CreateClient(); using (var testLock = new RedisLock(db, "testLock", "owner", TimeSpan.FromMilliseconds(50))) { Thread.Sleep(60); using (var testLock2 = new RedisLock(db, "testLock", "owner", TimeSpan.FromMilliseconds(10))) Assert.NotNull(testLock2); } }
/// <summary> /// 演示阻塞锁 /// </summary> /// <param name="redisManager"></param> /// <param name="index"></param> /// <returns></returns> private static async Task ShowNonBlockingLockAsync(RedisManager redisManager, int index) { Console.WriteLine($"{index} Start"); await using RedisLock redisLock = await redisManager.GetNonBlockingLockAsync("LockKey", 10000); if (redisLock == null) { return; } Console.WriteLine($"{index} End"); }
public void ExtendsALock() { var db = RedisUtils.CreateClient(); using (var testLock = new RedisLock(db, "testLock", "owner", TimeSpan.FromMilliseconds(100))) { Assert.NotNull(testLock); using (var testLock2 = new RedisLock(db, "testLock", "owner", TimeSpan.FromMilliseconds(10))) Assert.NotNull(testLock2); } }
public void LockReentry() { UseDatabase(Database => { using (var lock1 = new RedisLock(Redis.Storage.GetDatabase(), "lock", "1", TimeSpan.FromMilliseconds(30))) { using (var lock2 = new RedisLock(Database, "lock", "1", TimeSpan.FromMilliseconds(5))) { } } }); }
public void LockRelease() { UseDatabase(Database => { using (var lock1 = new RedisLock(Database, "lock", "1", TimeSpan.FromMinutes(1))) { } using (var lock2 = new RedisLock(Database, "lock", "2", TimeSpan.FromMinutes(1))) { } }); }
private void Remove(RedisLock @lock) { if (!_db.LockRelease(@lock.Key, @lock.Token)) { _logger.LogInformation("Lock on {Key} expired or the process doesn't own the lock", @lock.Key); } lock (_locks) { _locks.Remove(@lock); } }
public async Task AcquireFromNestedTask() { var db = RedisUtils.CreateClient(); using (var lock1 = RedisLock.Acquire(db, "test", TimeSpan.FromMilliseconds(50))) { Assert.NotNull(lock1); await Task.Delay(100); await Task.Run(() => NestedTask(db)); } }
public void LockCollision_WithTimeout() { UseDatabase(Database => { using (var lock1 = new RedisLock(Database, "lock", "1", TimeSpan.FromMilliseconds(30))) { Assert.Throws <TimeoutException>(() => { var lock2 = new RedisLock(Database, "lock", "2", TimeSpan.FromMilliseconds(1)); }); } }); }
public void LockCollision() { UseDatabase(Database => { using (var lock1 = new RedisLock(Database, "lock", "1", TimeSpan.FromMilliseconds(30))) { Thread.Sleep(20); //Sleep to give the wait loop time to run. If not set high enough lock2 will Timeout using (var lock2 = new RedisLock(Database, "lock", "2", TimeSpan.FromMilliseconds(30))) { } } }); }
public void LockCollision_WithTimeout() { UseDatabase(Database => { using (var lock1 = new RedisLock(Database, "lock", "1", TimeSpan.FromMilliseconds(30))) { Assert.Throws<TimeoutException>(() => { var lock2 = new RedisLock(Database, "lock", "2", TimeSpan.FromMilliseconds(1)); }); } }); }
public async Task <RedisLock> GetLockAsync() { using (var redisLock = await _redisLockFactory.CreateAsync(_resource, _expiry)) { _redisLock = redisLock; if (redisLock.IsAcquired) { Thread.Sleep(_interval); } return(redisLock); } }
public void ReleaseNestedAfterTimeout() { var db = RedisUtils.CreateClient(); using (var testLock1 = new RedisLock(db, "testLock", "owner", TimeSpan.FromMilliseconds(50))) { using (var testLock2 = new RedisLock(db, "testLock", "owner", TimeSpan.FromMilliseconds(1))) { } Thread.Sleep(60); using (var testLock2 = new RedisLock(db, "testLock", "otherOwner", TimeSpan.FromMilliseconds(1))) { }; Assert.True(true); } }
public void AcquireNested() { var db = RedisUtils.CreateClient(); using (var testLock1 = RedisLock.Acquire(db, "testLock", TimeSpan.FromMilliseconds(100))) { Assert.NotNull(testLock1); using (var testLock2 = RedisLock.Acquire(db, "testLock", TimeSpan.FromMilliseconds(100))) { Assert.NotNull(testLock2); } } }
public void NestLockDisposePreservesRoot() { var db = RedisUtils.CreateClient(); using (var testLock1 = new RedisLock(db, "testLock", "owner", TimeSpan.FromMilliseconds(1000))) { using (var testLock2 = new RedisLock(db, "testLock", "owner", TimeSpan.FromMilliseconds(1000))) { } Assert.Throws <TimeoutException>(() => { using (var testLock2 = new RedisLock(db, "testLock", "otherOwner", TimeSpan.FromMilliseconds(1))) { }; }); } }
public void LockReentry_DontReleaseEarly() { UseDatabase(Database => { using (var lock1 = new RedisLock(Database, "lock", "1", TimeSpan.FromMilliseconds(60))) { using (var lock3 = new RedisLock(Database, "lock", "1", TimeSpan.FromMilliseconds(5))) { } //Make sure the lock isn't removed when the nested lock is disposed Assert.Throws <TimeoutException>(() => { var lock2 = new RedisLock(Database, "lock", "2", TimeSpan.FromMilliseconds(1)); }); } }); }
public void LockReentry_ExtendLock() { UseDatabase(Database => { using (var lock1 = new RedisLock(Database, "lock", "1", TimeSpan.FromMilliseconds(10))) { using (var lock3 = new RedisLock(Database, "lock", "1", TimeSpan.FromMinutes(1))) { } Thread.Sleep(20); Assert.Throws <TimeoutException>(() => { var lock2 = new RedisLock(Database, "lock", "2", TimeSpan.FromMilliseconds(1)); }); } }); }
private void Extend(RedisLock @lock) { var result = _db.LockExtend(@lock.Key, @lock.Token, _expire); if (!result) { _logger.LogInformation("Log on {Key} expired or the process doesn't own the lock", @lock.Key); lock (_locks) { _locks.Remove(@lock); } throw new LockException($"Lock {@lock.Key} Expired or the process doesn't own the lock"); } @lock.AdquireLock(); }
public void GetLock_With_Multi_Threads_Test() { int threadCount = 10; var rl = new RedisLock(rk, rs, defaultExpire); var ls = new List <string>(); var count = 0; rk.Del("lockObj"); while (count <= 30) { ThreadPool.QueueUserWorkItem(s => { if (rl.GetLock()) { ls.Add("got!"); } count++; }); //Task.Run(new Action(() => //{ // if (rl.GetLock()) // ls.Add("got!"); // count++; //})); Thread.Sleep(10); } //for (int i = 0; i < threadCount; i++) //{ // new Thread(() => // { // if (rl.GetLock()) // ls.Add("got!"); // }).Start(); // Thread.Sleep(5); //} Thread.Sleep(10000); Assert.True(ls.Count > 0); }
public void LockReentry_DontReleaseEarly() { UseDatabase(Database => { using (var lock1 = new RedisLock(Database, "lock", "1", TimeSpan.FromMilliseconds(60))) { using (var lock3 = new RedisLock(Database, "lock", "1", TimeSpan.FromMilliseconds(5))) { } //Make sure the lock isn't removed when the nested lock is disposed Assert.Throws<TimeoutException>(() => { var lock2 = new RedisLock(Database, "lock", "2", TimeSpan.FromMilliseconds(1)); }); } }); }
public void LockReentry_ExtendLock() { UseDatabase(Database => { using (var lock1 = new RedisLock(Database, "lock", "1", TimeSpan.FromMilliseconds(10))) { using (var lock3 = new RedisLock(Database, "lock", "1", TimeSpan.FromMinutes(1))) { } Thread.Sleep(20); Assert.Throws<TimeoutException>(() => { var lock2 = new RedisLock(Database, "lock", "2", TimeSpan.FromMilliseconds(1)); }); } }); }
internal static void DoWork([NotNull] IDatabase redis, [NotNull] RedisKey key, [NotNull] TimeSpan timeOut, [NotNull] TimeSpan sleep, ref int concurrentCount) { try { using (var testLock = new RedisLock(redis, key, Thread.CurrentThread.ManagedThreadId.ToString(), timeOut)) { Thread.Sleep(sleep); concurrentCount++; }; } catch (TimeoutException) { } catch (Exception) { throw; } }
public override LockResult TryGetDistributedLock(TimeSpan?getlockTimeOut, TimeSpan?taskrunTimeOut) { if (lockresult == LockResult.Success) { throw new Exception("检测到当前锁已获取"); } _client = DistributedLockConfig.GetRedisPoolClient(); //当其获取锁后,redis连接资源会一直占用,直到获取锁的资源释放后,连接才会跳出,可能会导致连接池资源的浪费。 try { this._lock = new RedisLock(_client as RedisClient, key, getlockTimeOut); lockresult = LockResult.Success; } catch (Exception exp) { LogManager.DefaultLogger.Error(exp, "redis分布式尝试锁系统级别严重异常"); lockresult = LockResult.LockSystemExceptionFailure; } return(lockresult); }