public async Task RollbackTx(string _, RollbackSubTxMessage msg) { await this.storage.Unblock(msg.TxID); }
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()); } }