/// <summary> /// 取分布式锁(基于DB方式) /// </summary> /// <param name="moduleFlag">模块标识,模块表名/类名</param> /// <param name="method_Flag">方法名标识</param> /// <param name="expirtime">自定义过期时间(秒)</param> /// <param name="des">锁描述</param> /// <returns></returns> public static string DistributeDbLock(string moduleFlag, string method_Flag, double?expirtime = null, string des = null) { try { if (WebConfigHelper.GetAppSettingValue("EnabledDistributeLock") != "true") //未启用分布式锁 { return(string.Empty); } string hostname = System.Net.Dns.GetHostName(); //当前服务器 string processId = ApplicationObject.GetCurrentProcessId(); //当前进程 string threadId = ApplicationObject.GetCurrentThreadId(); //当前线程 lock (tempObjDistriLock) { string errMsg = string.Empty; int timeout = 30; //30秒超时 DateTime initTime = DateTime.Now; DatabaseType dbType = DatabaseType.MsSqlServer; string connStr = ModelConfigHelper.GetModelConnStr(typeof(Other_DistributedLock), out dbType, false); while ((DateTime.Now - initTime).TotalSeconds <= timeout) { double updateTimesamp = Globals.GetTimestamp(DateTime.Now); //当前时间戳 double invalidTimesamp = expirtime.HasValue && expirtime.Value > 0 ? updateTimesamp + expirtime.Value : updateTimesamp + 20; //过期时间戳 Other_DistributedLock methodLock = CommonOperate.GetEntity <Other_DistributedLock>(x => x.ModuleFlag == moduleFlag && x.Method_Flag == method_Flag && x.Invalid_Timesamp > updateTimesamp, null, out errMsg); //锁存在,继续循环再取 if (methodLock != null) { Thread.Sleep(10); continue; } //锁不存在,取得锁成功,插入锁标识 methodLock = new Other_DistributedLock() { ModuleFlag = moduleFlag, Method_Flag = method_Flag, Update_Timesamp = updateTimesamp, Invalid_Timesamp = invalidTimesamp, Maching = hostname, ProcessId = processId, ThreadId = threadId, Des = des }; TransactionTask tranAction = (conn) => { CommonOperate.DeleteRecordsByExpression <Other_DistributedLock>(x => x.ModuleFlag == moduleFlag && x.Method_Flag == method_Flag, out errMsg, false, connStr, dbType, conn); if (!string.IsNullOrEmpty(errMsg)) { throw new Exception(errMsg); } CommonOperate.OperateRecord <Other_DistributedLock>(methodLock, ModelRecordOperateType.Add, out errMsg, null, false, false, connStr, dbType, conn); if (!string.IsNullOrEmpty(errMsg)) { throw new Exception(errMsg); } }; CommonOperate.TransactionHandle(tranAction, out errMsg, connStr, dbType); //取锁成功 if (string.IsNullOrEmpty(errMsg)) { return(string.Empty); } else { WritLockLog(moduleFlag, method_Flag, errMsg); } //取锁失败,继续循环取 Thread.Sleep(10); } return("获取分布式锁超时"); //取锁失败 } } catch { return(string.Empty); } }