示例#1
0
 public async Task RollbackTx(string _, RollbackSubTxMessage msg)
 {
     await this.storage.Unblock(msg.TxID);
 }
示例#2
0
        public async Task AbortTx(string txId, int timeoutMs)
        {
            var proposerId = this.locator.GetRandomProposer();
            var reqId      = Guid.NewGuid().ToString();

            var result      = new TaskCompletionSource <IEnumerable <string> >();
            var localMutex  = new object();
            var hasFinished = false;

            this.bus.AbortTx(proposerId, new TxAbortMessage(reqId, txId));

            var handler1 = this.bus.WaitForAbortConfirmed(reqId, (msg, senderId) =>
            {
                lock (localMutex)
                {
                    if (hasFinished)
                    {
                        return(WaitStrategy.StopWaiting);
                    }
                    if (senderId != proposerId)
                    {
                        return(WaitStrategy.KeepWaiting);
                    }

                    hasFinished = true;
                    result.SetResult(msg.ShardIDs);
                    return(WaitStrategy.StopWaiting);
                }
            });

            var handler2 = this.bus.WaitForAbortFailed(reqId, (msg, senderId) =>
            {
                lock (localMutex)
                {
                    if (hasFinished)
                    {
                        return(WaitStrategy.StopWaiting);
                    }
                    if (senderId != proposerId)
                    {
                        return(WaitStrategy.KeepWaiting);
                    }

                    hasFinished = true;
                    result.SetException(new AlreadyCommittedException(txId, msg.ShardKeyValueUpdate));
                    return(WaitStrategy.StopWaiting);
                }
            });

            this.timer.SetTimeout(() =>
            {
                lock (localMutex)
                {
                    if (hasFinished)
                    {
                        return;
                    }
                    hasFinished = true;
                    result.SetException(new TxUnknownException(txId));
                    handler1.Dispose();
                    handler2.Dispose();
                }
            }, timeoutMs);

            var shardIds = await result.Task;

            var rollbackMsg = new RollbackSubTxMessage(txId);

            foreach (var shardId in shardIds)
            {
                this.bus.RollbackTx(shardId, rollbackMsg.Clone());
            }
        }