Пример #1
0
        public async Task RollbackTransaction(long transactionId)
        {
            if (Logger.IsEnabled(LogLevel.Trace))
            {
                Logger.LogTrace("Start rollback transaction with id = {0},event counts = {1}, from version {2} to version {3}", GrainId.ToString(), WaitingForTransactionTransports.Count.ToString(), CurrentTransactionStartVersion.ToString(), Snapshot.Base.Version.ToString());
            }
            if (CurrentTransactionId == transactionId && CurrentTransactionStartVersion != -1 && Snapshot.Base.Version >= CurrentTransactionStartVersion)
            {
                try
                {
                    if (BackupSnapshot.Base.Version == CurrentTransactionStartVersion - 1)
                    {
                        Snapshot = new Snapshot <PrimaryKey, StateType>(GrainId)
                        {
                            Base  = BackupSnapshot.Base.Clone(),
                            State = BackupSnapshot.State.Clone()
                        };
                    }
                    else
                    {
                        if (BackupSnapshot.Base.Version >= CurrentTransactionStartVersion)
                        {
                            await EventStorage.DeleteEnd(Snapshot.Base.StateId, CurrentTransactionStartVersion, Snapshot.Base.LatestMinEventTimestamp);
                        }
                        await RecoverySnapshot();
                    }

                    WaitingForTransactionTransports.Clear();
                    RestoreTransactionTemporaryState();
                    TransactionSemaphore.Release();
                    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;
                }
            }
        }
Пример #2
0
        protected async Task BeginTransaction(long transactionId)
        {
            if (Logger.IsEnabled(LogLevel.Trace))
            {
                Logger.LogTrace("Begin transaction with grainid {0} and transactionId {1},transaction start state version {2}", GrainId.ToString(), transactionId, CurrentTransactionStartVersion.ToString());
            }
            if (TransactionStartMilliseconds != 0 &&
                DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - TransactionStartMilliseconds > CoreOptions.TransactionMillisecondsTimeout)
            {
                if (await TransactionTimeoutLock.WaitAsync(CoreOptions.TransactionMillisecondsTimeout))
                {
                    try
                    {
                        if (TransactionStartMilliseconds != 0 &&
                            DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - TransactionStartMilliseconds > CoreOptions.TransactionMillisecondsTimeout)
                        {
                            await RollbackTransaction(CurrentTransactionId);//事务超时自动回滚

                            Logger.LogError("Transaction timeout, automatic rollback,grain id = {1}", GrainId.ToString());
                        }
                    }
                    finally
                    {
                        TransactionTimeoutLock.Release();
                    }
                }
            }
            if (await TransactionSemaphore.WaitAsync(CoreOptions.TransactionMillisecondsTimeout))
            {
                try
                {
                    SnapshotCheck();
                    CurrentTransactionStartVersion = Snapshot.Base.Version + 1;
                    CurrentTransactionId           = transactionId;
                    TransactionStartMilliseconds   = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                }
                catch
                {
                    TransactionSemaphore.Release();
                    throw;
                }
            }
            else
            {
                throw new BeginTxTimeoutException(GrainId.ToString(), transactionId, GrainType);
            }
        }
Пример #3
0
 public async Task CommitTransaction(long transactionId)
 {
     if (Logger.IsEnabled(LogLevel.Trace))
     {
         Logger.LogTrace("Commit transaction with id = {0},event counts = {1}, from version {2} to version {3}", GrainId.ToString(), WaitingForTransactionTransports.Count.ToString(), CurrentTransactionStartVersion.ToString(), Snapshot.Base.Version.ToString());
     }
     if (WaitingForTransactionTransports.Count > 0)
     {
         if (CurrentTransactionId != transactionId)
         {
             throw new TxCommitException();
         }
         try
         {
             var onCommitTask = OnCommitTransaction(transactionId);
             if (!onCommitTask.IsCompletedSuccessfully)
             {
                 await onCommitTask;
             }
             foreach (var transport in WaitingForTransactionTransports)
             {
                 var startTask = OnRaiseStart(transport.FullyEvent);
                 if (!startTask.IsCompletedSuccessfully)
                 {
                     await startTask;
                 }
                 transport.BytesTransport = new EventBytesTransport(
                     TypeContainer.GetTypeCode(transport.FullyEvent.Event.GetType()),
                     GrainId,
                     transport.FullyEvent.Base.GetBytes(),
                     Serializer.SerializeToBytes(transport.FullyEvent.Event)
                     );
             }
             await EventStorage.TransactionBatchAppend(WaitingForTransactionTransports);
         }
         catch (Exception ex)
         {
             Logger.LogError(ex, "Commit transaction failed, grain Id = {1}", GrainId.ToString());
             throw;
         }
     }
 }
Пример #4
0
 public async Task CommitTransaction(long transactionId)
 {
     if (Logger.IsEnabled(LogLevel.Trace))
     {
         Logger.LogTrace("Commit transaction with id = {0},event counts = {1}, from version {2} to version {3}", GrainId.ToString(), WaitingForTransactionTransports.Count.ToString(), CurrentTransactionStartVersion.ToString(), Snapshot.Base.Version.ToString());
     }
     if (WaitingForTransactionTransports.Count > 0)
     {
         if (CurrentTransactionId != transactionId)
         {
             throw new TransactionCommitException();
         }
         try
         {
             //如果是带Id的事务,则加入事务事件,等待Complete
             if (transactionId > 0)
             {
                 TransactionRaiseEvent(new TransactionCommitEvent(CurrentTransactionId, CurrentTransactionStartVersion + 1, WaitingForTransactionTransports.Min(t => t.FullyEvent.Base.Timestamp)));
             }
             foreach (var transport in WaitingForTransactionTransports)
             {
                 var startTask = OnRaiseStart(transport.FullyEvent);
                 if (!startTask.IsCompletedSuccessfully)
                 {
                     await startTask;
                 }
                 transport.BytesTransport = new EventBytesTransport
                 {
                     EventType  = transport.FullyEvent.Event.GetType().FullName,
                     GrainId    = GrainId,
                     EventBytes = Serializer.SerializeToBytes(transport.FullyEvent.Event),
                     BaseBytes  = transport.FullyEvent.Base.GetBytes()
                 };
             }
             await EventStorage.TransactionBatchAppend(WaitingForTransactionTransports);
         }
         catch (Exception ex)
         {
             Logger.LogError(ex, "Commit transaction failed, grain Id = {1}", GrainId.ToString());
             throw;
         }
     }
 }