예제 #1
0
 /// <summary>
 /// 更新事务分表状态
 /// </summary>
 /// <param name="id">事务分表的主键</param>
 /// <param name="status">更新状态</param>
 public void UpdateTransPartsStatus(long?id, byte status)
 {
     using (DbContext dbContext = CreateDbContext())
     {
         DistributedTransactionPart updateBefore = new DistributedTransactionPart {
             Id = id
         };
         dbContext.Set <DistributedTransactionPart>().Attach(updateBefore);
         updateBefore.TransactionStatus = status;
         dbContext.SaveChanges();
     }
 }
예제 #2
0
 /// <summary>
 /// 分布式删除数据的逆操作,当事务失败时调用
 /// </summary>
 /// <param name="entity">实体对象</param>
 public void DistributedInsertInverse(DistributedTransactionPart distributedTransactionPart)
 {
     using (BaseDbContext dbContext = CreateDbContext())
     {
         TEntity entity = JsonConvert.DeserializeObject <TEntity>(CompressHelper.GZipDecompressString(distributedTransactionPart.InverseOper));
         dbContext.Entry(entity).State = EntityState.Added;
         DistributedTransactionPart beforePart = new DistributedTransactionPart {
             Id = distributedTransactionPart.Id
         };
         dbContext.Set <DistributedTransactionPart>().Attach(beforePart);
         beforePart.TransactionStatus = 2;
         dbContext.SaveChanges();
     }
 }
예제 #3
0
 /// <summary>
 /// 分布式插入数据的反操作。当事务失败时调用
 /// </summary>
 /// <param name="distributedTransactionPart">分表对象</param>
 public abstract void DistributedDeleteInverse(DistributedTransactionPart distributedTransactionPart);
예제 #4
0
        /// <summary>
        /// 分布式数据操作拦截,会对更新、删除、插入数据进行记录,
        /// 用于异步确定、异步回滚
        /// </summary>
        /// <param name="invocation"></param>
        public void Intercept(IInvocation invocation)
        {
            string MethodName = invocation.Method.Name;
            long?  transId    = DistributedTransactionScan.TransactionIds.Value;

            if (transId != null && MethodNames.Contains(MethodName))
            {
                dynamic target = invocation.InvocationTarget;
                using (TransactionScope tx = new TransactionScope())
                {
                    using (BaseDbContext baseDbContext = target.CreateDbContext())
                    {
                        if (invocation.Arguments[0] is IEntity)
                        {
                            IEntity entity = (IEntity)invocation.Arguments[0];
                            if (entity != null)
                            {
                                DistributedTransactionPart distributedTransactionPart = new DistributedTransactionPart
                                {
                                    Id = AllStatic.IdWorker.NextId(),
                                    DistributedTransactionMainId = (long)DistributedTransactionScan.TransactionIds.Value,
                                    TransTableName     = entity.TableName(),
                                    TransPrimaryKeyVal = entity.Key,
                                    TransactionStatus  = 0,
                                    CreateDate         = DateTime.Now,
                                };
                                if (MethodName == "Insert")
                                {
                                    RecordDistribute(baseDbContext.Database.Connection.ConnectionString, entity.TableName());
                                    distributedTransactionPart.InverseOperType            = "d";
                                    baseDbContext.Entry(distributedTransactionPart).State = EntityState.Added;
                                }
                                else if (MethodName == "Delete")
                                {
                                    var beforeData = target.FindEntity(entity.Key);
                                    if (beforeData != null)
                                    {
                                        RecordDistribute(baseDbContext.Database.Connection.ConnectionString, entity.TableName());
                                        distributedTransactionPart.InverseOper                = CompressHelper.GZipCompressString(JsonConvert.SerializeObject(beforeData, AllStatic.TimeConverter));
                                        distributedTransactionPart.InverseOperType            = "i";
                                        baseDbContext.Entry(distributedTransactionPart).State = EntityState.Added;
                                    }
                                }
                                else if (MethodName == "UpdateAll" || MethodName == "UpdateChange")
                                {
                                    var beforeData = target.FindEntity(entity.Key);
                                    if (beforeData != null)
                                    {
                                        RecordDistribute(baseDbContext.Database.Connection.ConnectionString, entity.TableName());
                                        distributedTransactionPart.InverseOper                = CompressHelper.GZipCompressString(JsonConvert.SerializeObject(beforeData, AllStatic.TimeConverter));
                                        distributedTransactionPart.InverseOperType            = "u";
                                        baseDbContext.Entry(distributedTransactionPart).State = EntityState.Added;
                                    }
                                }
                            }
                        }
                        else if (invocation.Arguments[0] is IList)
                        {
                            foreach (IEntity entity in (IList)invocation.Arguments[0])
                            {
                                if (entity != null)
                                {
                                    DistributedTransactionPart distributedTransactionPart = new DistributedTransactionPart
                                    {
                                        Id = AllStatic.IdWorker.NextId(),
                                        DistributedTransactionMainId = (long)DistributedTransactionScan.TransactionIds.Value,
                                        TransTableName     = entity.TableName(),
                                        TransPrimaryKeyVal = entity.Key,
                                        TransactionStatus  = 0,
                                        CreateDate         = DateTime.Now,
                                    };
                                    if (MethodName == "Insert")
                                    {
                                        RecordDistribute(baseDbContext.Database.Connection.ConnectionString, entity.TableName());
                                        distributedTransactionPart.InverseOper                = Convert.ToString(entity.Key);
                                        distributedTransactionPart.InverseOperType            = "D";
                                        baseDbContext.Entry(distributedTransactionPart).State = EntityState.Added;
                                    }
                                    else if (MethodName == "Delete")
                                    {
                                        var beforeData = target.FindEntity(entity.Key);
                                        if (beforeData != null)
                                        {
                                            RecordDistribute(baseDbContext.Database.Connection.ConnectionString, entity.TableName());
                                            distributedTransactionPart.InverseOper                = CompressHelper.GZipCompressString(JsonConvert.SerializeObject(beforeData, AllStatic.TimeConverter));
                                            distributedTransactionPart.InverseOperType            = "I";
                                            baseDbContext.Entry(distributedTransactionPart).State = EntityState.Added;
                                        }
                                    }
                                    else if (MethodName == "UpdateAll" || MethodName == "UpdateChange")
                                    {
                                        var beforeData = target.FindEntity(entity.Key);
                                        if (beforeData != null)
                                        {
                                            RecordDistribute(baseDbContext.Database.Connection.ConnectionString, entity.TableName());
                                            distributedTransactionPart.InverseOper                = CompressHelper.GZipCompressString(JsonConvert.SerializeObject(beforeData, AllStatic.TimeConverter));
                                            distributedTransactionPart.InverseOperType            = "U";
                                            baseDbContext.Entry(distributedTransactionPart).State = EntityState.Added;
                                        }
                                    }
                                }
                            }
                        }
                        baseDbContext.SaveChanges();
                    }
                    invocation.Proceed();
                    tx.Complete();
                }
            }
            else
            {
                invocation.Proceed();
            }
        }
예제 #5
0
 /// <summary>
 /// 检查分布式事务是否为成功提交,只有提交成功才能继续操作,提交失败则无法继续操作
 /// </summary>
 /// <param name="primaryKeyVal">主键的值</param>
 /// <param name="transTableName">事务操作的表名称</param>
 public void CheckTransactionFinish(long?primaryKeyVal, string transTableName)
 {
     using (DbContext dbContext = CreateDbContext())
     {
         var query = dbContext.Set <DistributedTransactionPart>().AsNoTracking().AsQueryable().Where(a => a.TransTableName == transTableName && a.TransPrimaryKeyVal == primaryKeyVal && a.TransactionStatus == 0);
         if (query.Any())
         {
             DistributedTransactionPart distributedTransactionPart = query.FirstOrDefault();
             var result = ReadOnlyMainDbContext.DistributedTransactionMains.AsNoTracking().AsQueryable().Where(a => a.Id == distributedTransactionPart.DistributedTransactionMainId && a.TransactionStatus == 1).Any();
             List <DistributedTransactionMainDetail> mainDetails = ReadOnlyMainDbContext.DistributedTransactionMainDetails.AsNoTracking().AsQueryable().Where(a => a.DistributedTransactionMainId == distributedTransactionPart.DistributedTransactionMainId).ToList();
             if (mainDetails.Count == 0)
             {
                 InverseRepository <TEntity> inverseRepository = CurrentInverse();
                 if (result)
                 {
                     inverseRepository.UpdateTransPartsStatus(distributedTransactionPart.Id, 1);
                 }
                 else
                 {
                     if (distributedTransactionPart.InverseOperType == "D" || distributedTransactionPart.InverseOperType == "d")
                     {
                         inverseRepository.DistributedDeleteInverse(distributedTransactionPart);
                     }
                     else if (distributedTransactionPart.InverseOperType == "I" || distributedTransactionPart.InverseOperType == "i")
                     {
                         inverseRepository.DistributedInsertInverse(distributedTransactionPart);
                     }
                     else if (distributedTransactionPart.InverseOperType == "U" || distributedTransactionPart.InverseOperType == "u")
                     {
                         inverseRepository.DistributedUpdateInverse(distributedTransactionPart);
                     }
                 }
             }
             else
             {
                 foreach (DistributedTransactionMainDetail mainDetail in mainDetails)
                 {
                     var inverseRepository = AllStatic.InverseRepositoryMap[mainDetail.TransactionDataSource][mainDetail.TransactionTable];
                     List <DistributedTransactionPart> distributedTransactionPartList = inverseRepository.FindTransPartsById(distributedTransactionPart.DistributedTransactionMainId);
                     if (result)
                     {
                         inverseRepository.UpdateTransPartsStatus(distributedTransactionPartList.Select(a => a.Id).ToList(), 1);
                     }
                     else
                     {
                         //批量插入的逆操作
                         List <DistributedTransactionPart> dparts = new List <DistributedTransactionPart>();
                         //批量删除的逆操作
                         List <DistributedTransactionPart> iparts = new List <DistributedTransactionPart>();
                         //批量更新的逆操作
                         List <DistributedTransactionPart> uparts = new List <DistributedTransactionPart>();
                         foreach (DistributedTransactionPart part in distributedTransactionPartList)
                         {
                             if (part.InverseOperType == "D")
                             {
                                 dparts.Add(part);
                             }
                             else if (part.InverseOperType == "d")
                             {
                                 inverseRepository.DistributedDeleteInverse(part);
                             }
                             else if (part.InverseOperType == "I")
                             {
                                 iparts.Add(part);
                             }
                             else if (part.InverseOperType == "i")
                             {
                                 inverseRepository.DistributedInsertInverse(part);
                             }
                             else if (part.InverseOperType == "U")
                             {
                                 uparts.Add(part);
                             }
                             else if (part.InverseOperType == "u")
                             {
                                 inverseRepository.DistributedUpdateInverse(part);
                             }
                             inverseRepository.DistributedDeleteInverse(dparts);
                             inverseRepository.DistributedInsertInverse(iparts);
                             inverseRepository.DistributedUpdateInverse(uparts);
                         }
                     }
                 }
             }
         }
     }
 }