public void RemoveAuthorWithBooksUsingTransaction() { var transactionTask = new TransactionTask(dbContext => { var firstAuthor = dbContext.Set <Author>().FirstOrDefault(a => a.Books.Any()); dbContext.Remove(firstAuthor); dbContext.SaveChanges(); }); var transanctionTaskResult = transactionTaskManager.UseTransaction(transactionTask); transanctionTaskResult.Failure.Should().BeTrue(); transanctionTaskResult.Exception.Should().BeAssignableTo <DbUpdateException>(); }
private TransactionTaskResult TryUseTransaction(TransactionTask transactionTask) { using (var dbContext = _newDbContext()) using (var transaction = dbContext.Database.BeginTransaction()) try { transactionTask.Action(dbContext); dbContext.SaveChanges(); transaction.Commit(); var transactionTaskSuccess = new TransactionTaskResult(transaction.TransactionId, transactionTask); return(transactionTaskSuccess); } catch (Exception e) { transaction.Rollback(); var transactionTaskFailure = new TransactionTaskResult(transaction.TransactionId, transactionTask, e); return(transactionTaskFailure); } }
public void InsertAndUpdateBooksUsingTransaction() { var newAuthor = fakerAuthor.Generate(); var transactionTask = new TransactionTask(dbContext => { var authorDbSet = dbContext.Set <Author>(); var bookDbSet = dbContext.Set <Book>(); authorDbSet.Add(newAuthor); var authorsInserted = dbContext.SaveChanges(); var firstAuthor = authorDbSet.FirstOrDefault(); var booksFirstAuthor = bookDbSet.AsTracking().Where(b => b.AuthorId == firstAuthor.AuthorId).ToList(); booksFirstAuthor.ForEach(b => b.AuthorId = newAuthor.AuthorId); var booksUpdated = dbContext.SaveChanges(); }); var transanctionTaskResult = transactionTaskManager.UseTransaction(transactionTask); transanctionTaskResult.Success.Should().BeTrue(); }
/// <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); } }
/// <summary> /// 执行事务 /// </summary> /// <param name="transTask">事务处理函数</param> /// <param name="errorMsg">异常信息</param> /// <param name="connString">数据库连接字符串</param> public abstract void TransactionHandle(TransactionTask transTask, out string errorMsg, string connString = null);
/// <summary> /// 执行事务 /// </summary> /// <param name="transTask">事务处理函数</param> /// <param name="errorMsg">异常信息</param> /// <param name="connString">数据库连接字符串</param> public void TransactionHandle(TransactionTask transTask, out string errorMsg, string connString = null) { errorMsg = string.Empty; _dal.TransactionHandle(transTask, out errorMsg, connString); }
public TransactionTaskResult UseTransaction(TransactionTask transactionTask) => transactionTask is null ? throw new ArgumentNullException(nameof(transactionTask))