예제 #1
0
 protected async ValueTask BeginTransaction()
 {
     if (Logger.IsEnabled(LogLevel.Trace))
     {
         Logger.LogTrace("Begin transaction with id {0},transaction start state version {1}", GrainId.ToString(), TransactionStartVersion.ToString());
     }
     try
     {
         if (TransactionPending)
         {
             if ((DateTimeOffset.UtcNow - BeginTransactionTime).TotalSeconds > CoreOptions.TransactionTimeoutSeconds)
             {
                 var rollBackTask = RollbackTransaction();//事务阻赛超过一分钟自动回滚
                 if (!rollBackTask.IsCompletedSuccessfully)
                 {
                     await rollBackTask;
                 }
                 Logger.LogError("Transaction timeout, automatic rollback,grain id = {1}", GrainId.ToString());
             }
             else
             {
                 throw new RepeatedTransactionException(GrainId.ToString(), GetType());
             }
         }
         var checkTask = TransactionStateCheck();
         if (!checkTask.IsCompletedSuccessfully)
         {
             await checkTask;
         }
         TransactionPending      = true;
         TransactionStartVersion = Snapshot.Base.Version;
         BeginTransactionTime    = DateTimeOffset.UtcNow;
         if (Logger.IsEnabled(LogLevel.Trace))
         {
             Logger.LogTrace("Begin transaction successfully with id {0},transaction start state version {1}", GrainId.ToString(), TransactionStartVersion.ToString());
         }
     }
     catch (Exception ex)
     {
         Logger.LogCritical(ex, "Begin transaction failed, grain Id = {1}", GrainId.ToString());
         throw;
     }
 }
예제 #2
0
        protected async Task CommitTransaction()
        {
            if (Logger.IsEnabled(LogLevel.Trace))
            {
                Logger.LogTrace("Commit transaction with id = {0},event counts = {1}, from version {2} to version {3}", GrainId.ToString(), WaitingForTransactionEvents.Count.ToString(), TransactionStartVersion.ToString(), Snapshot.Base.Version.ToString());
            }
            if (WaitingForTransactionEvents.Count > 0)
            {
                try
                {
                    foreach (var transport in WaitingForTransactionEvents)
                    {
                        var startTask = OnRaiseStart(transport.FullyEvent);
                        if (!startTask.IsCompletedSuccessfully)
                        {
                            await startTask;
                        }
                        transport.BytesTransport = new EventBytesTransport
                        {
                            EventType  = transport.FullyEvent.Event.GetType().FullName,
                            ActorId    = GrainId,
                            EventBytes = Serializer.SerializeToBytes(transport.FullyEvent.Event),
                            BaseBytes  = transport.FullyEvent.Base.GetBytes()
                        };
                    }
                    await EventStorage.TransactionBatchAppend(WaitingForTransactionEvents);

                    foreach (var transport in WaitingForTransactionEvents)
                    {
                        var task = OnRaiseSuccessed(transport.FullyEvent, transport.BytesTransport);
                        if (!task.IsCompletedSuccessfully)
                        {
                            await task;
                        }
                    }
                    var saveSnapshotTask = SaveSnapshotAsync();
                    if (!saveSnapshotTask.IsCompletedSuccessfully)
                    {
                        await saveSnapshotTask;
                    }
                    var handlers = FollowUnit.GetAllEventHandlers();
                    if (handlers.Count > 0)
                    {
                        try
                        {
                            foreach (var transport in WaitingForTransactionEvents)
                            {
                                if (CoreOptions.PriorityAsyncEventBus)
                                {
                                    try
                                    {
                                        var publishTask = EventBusProducer.Publish(transport.BytesTransport.GetBytes(), transport.HashKey);
                                        if (!publishTask.IsCompletedSuccessfully)
                                        {
                                            await publishTask;
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        Logger.LogError(ex, "EventBus error,state  Id ={0}, version ={1}", GrainId.ToString(), Snapshot.Base.Version);

                                        //当消息队列出现问题的时候同步推送
                                        await Task.WhenAll(handlers.Select(func => func(transport.BytesTransport.GetBytes())));
                                    }
                                }
                                else
                                {
                                    try
                                    {
                                        await Task.WhenAll(handlers.Select(func => func(transport.BytesTransport.GetBytes())));
                                    }
                                    catch (Exception ex)
                                    {
                                        Logger.LogError(ex, "EventBus error,state  Id ={0}, version ={1}", GrainId.ToString(), Snapshot.Base.Version);
                                        //当消息队列出现问题的时候异步推送
                                        var publishTask = EventBusProducer.Publish(transport.BytesTransport.GetBytes(), transport.HashKey);
                                        if (!publishTask.IsCompletedSuccessfully)
                                        {
                                            await publishTask;
                                        }
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.LogError(ex, "EventBus error,state  Id ={0}, version ={1}", GrainId.ToString(), Snapshot.Base.Version);
                        }
                    }
                    if (Logger.IsEnabled(LogLevel.Trace))
                    {
                        Logger.LogTrace("Commit transaction with id {0},event counts = {1}, from version {2} to version {3}", GrainId.ToString(), WaitingForTransactionEvents.Count.ToString(), TransactionStartVersion.ToString(), Snapshot.Base.Version.ToString());
                    }
                }
                catch (Exception ex)
                {
                    Logger.LogError(ex, "Commit transaction failed, grain Id = {1}", GrainId.ToString());
                    throw;
                }
                finally
                {
                    WaitingForTransactionEvents.Clear();
                    TransactionPending = false;
                }
            }
        }
예제 #3
0
 protected async ValueTask RollbackTransaction()
 {
     if (TransactionPending)
     {
         if (Logger.IsEnabled(LogLevel.Trace))
         {
             Logger.LogTrace("Rollback transaction successfully with id = {0},event counts = {1}, from version {2} to version {3}", GrainId.ToString(), WaitingForTransactionEvents.Count.ToString(), TransactionStartVersion.ToString(), Snapshot.Base.Version.ToString());
         }
         try
         {
             if (BackupSnapshot.Base.Version == TransactionStartVersion)
             {
                 Snapshot = new Snapshot <PrimaryKey, State>(GrainId)
                 {
                     Base  = BackupSnapshot.Base.Clone(),
                     State = BackupSnapshot.State.Clone()
                 };
             }
             else
             {
                 await RecoveryState();
             }
             WaitingForTransactionEvents.Clear();
             TransactionPending = false;
             if (Logger.IsEnabled(LogLevel.Trace))
             {
                 Logger.LogTrace("Rollback transaction successfully with id = {0},state version = {1}", GrainId.ToString(), Snapshot.Base.Version.ToString());
             }
         }
         catch (Exception ex)
         {
             Logger.LogCritical(ex, "Rollback transaction failed with Id = {1}", GrainId.ToString());
             throw;
         }
     }
 }