private async Task <MongoDbRecord> LockRecord(byte[] lockToken, Record r) { var key = r.Key.ToByteArray(); var version = r.Version.ToByteArray(); if (version.Length != 0) { var res = await RecordCollection.FindOneAndUpdateAsync( x => x.Key.Equals(key) && x.Version.Equals(version) && (x.TransactionLock == null || x.TransactionLock.Equals(lockToken)), Builders <MongoDbRecord> .Update .Set(x => x.TransactionLock, lockToken) ); if (res == null) { var e = new ConcurrentMutationException(r); e.Data["ExceptionType"] = "LockRecord"; throw e; } #if DEBUG Logger.LogDebug($"Locked token {new ByteString(lockToken)} {r.Key.ToString()}"); #endif return(res); } return(null); }
public async Task AddTransaction_InsertError() { ByteString mutationHash = await AddTransaction( new Record(binaryData[0], binaryData[1], ByteString.Empty), new Record(binaryData[3], binaryData[4], ByteString.Empty)); // Actual version: Non empty / Provided version: Empty (Write) ConcurrentMutationException exception1 = await Assert.ThrowsAsync <ConcurrentMutationException>(() => AddTransaction( new Record(binaryData[0], binaryData[2], ByteString.Empty))); // Actual version: Non empty / Provided version: Empty (Version check) ConcurrentMutationException exception2 = await Assert.ThrowsAsync <ConcurrentMutationException>(() => AddTransaction( new Record(binaryData[3], null, ByteString.Empty))); IReadOnlyList <Record> records1 = await this.Store.GetRecords(new[] { binaryData[0] }); IReadOnlyList <Record> records2 = await this.Store.GetRecords(new[] { binaryData[3] }); Assert.Equal(1, records1.Count); AssertRecord(records1[0], binaryData[0], binaryData[1], mutationHash); AssertRecord(exception1.FailedMutation, binaryData[0], binaryData[2], ByteString.Empty); Assert.Equal(1, records2.Count); AssertRecord(records2[0], binaryData[3], binaryData[4], mutationHash); AssertRecord(exception2.FailedMutation, binaryData[3], null, ByteString.Empty); }
private async Task UnlockRecord(byte[] lockToken, Record r) { var key = r.Key.ToByteArray(); var res = await RecordCollection.UpdateOneAsync( x => x.Key.Equals(key) && x.TransactionLock == lockToken, Builders <MongoDbRecord> .Update .Unset(x => x.TransactionLock) ); if (res.ModifiedCount != 1 || res.MatchedCount != 1) { var e = new ConcurrentMutationException(r); e.Data["ExceptionType"] = "UnlockRecord"; throw e; } #if DEBUG Logger.LogDebug($"Unlocked token {new ByteString(lockToken)} {r.Key.ToString()}"); #endif }
public async Task AddTransaction_InsertError() { ConcurrentMutationException exception1 = await Assert.ThrowsAsync <ConcurrentMutationException>(() => AddTransaction( new Record(binaryData[0], binaryData[1], binaryData[2]))); ConcurrentMutationException exception2 = await Assert.ThrowsAsync <ConcurrentMutationException>(() => AddTransaction( new Record(binaryData[3], null, binaryData[4]))); IList <Record> records1 = await this.store.GetRecords(new[] { binaryData[0] }); IList <Record> records2 = await this.store.GetRecords(new[] { binaryData[3] }); Assert.Equal(1, records1.Count); AssertRecord(records1[0], binaryData[0], ByteString.Empty, ByteString.Empty); AssertRecord(exception1.FailedMutation, binaryData[0], binaryData[1], binaryData[2]); Assert.Equal(1, records2.Count); AssertRecord(records2[0], binaryData[3], ByteString.Empty, ByteString.Empty); AssertRecord(exception2.FailedMutation, binaryData[3], null, binaryData[4]); }
public async Task AddTransaction_MultipleTransactionsError() { IList <Record> records1 = new Record[] { new Record(binaryData[0], binaryData[1], ByteString.Empty), new Record(binaryData[2], binaryData[3], ByteString.Empty), }; ByteString mutation1 = new ByteString(MessageSerializer.SerializeMutation(new Mutation(ByteString.Empty, records1, ByteString.Empty))); IList <Record> records2 = new Record[] { new Record(binaryData[2], binaryData[5], ByteString.Empty), new Record(binaryData[6], binaryData[7], ByteString.Empty), }; ByteString mutation2 = new ByteString(MessageSerializer.SerializeMutation(new Mutation(ByteString.Empty, records2, ByteString.Empty))); // Submit both transactions at once ConcurrentMutationException exception = await Assert.ThrowsAsync <ConcurrentMutationException>(() => this.Store.AddTransactions(new[] { new ByteString(MessageSerializer.SerializeTransaction(new Transaction(mutation1, new DateTime(), ByteString.Empty))), new ByteString(MessageSerializer.SerializeTransaction(new Transaction(mutation2, new DateTime(), ByteString.Empty))) })); IReadOnlyList <Record> result1 = await this.Store.GetRecords(new[] { binaryData[0] }); IReadOnlyList <Record> result2 = await this.Store.GetRecords(new[] { binaryData[2] }); IReadOnlyList <Record> result3 = await this.Store.GetRecords(new[] { binaryData[6] }); AssertRecord(exception.FailedMutation, binaryData[2], binaryData[5], ByteString.Empty); AssertRecord(result1[0], binaryData[0], ByteString.Empty, ByteString.Empty); AssertRecord(result2[0], binaryData[2], ByteString.Empty, ByteString.Empty); AssertRecord(result3[0], binaryData[6], ByteString.Empty, ByteString.Empty); }
private async Task UnlockRecord(byte[] lockToken, Record r) { var key = r.Key.ToByteArray(); var res = await RecordCollection.UpdateOneAsync( x => x.Key.Equals(key) && x.TransactionLock == lockToken, Builders<MongoDbRecord>.Update .Unset(x => x.TransactionLock) ); if (res.ModifiedCount != 1 || res.MatchedCount != 1) { var e = new ConcurrentMutationException(r); e.Data["ExceptionType"] = "UnlockRecord"; throw e; } #if DEBUG Logger.LogDebug($"Unlocked token {new ByteString(lockToken)} {r.Key.ToString()}"); #endif }
private async Task<MongoDbRecord> LockRecord(byte[] lockToken, Record r) { var key = r.Key.ToByteArray(); var version = r.Version.ToByteArray(); if (version.Length != 0) { var res = await RecordCollection.FindOneAndUpdateAsync( x => x.Key.Equals(key) && x.Version.Equals(version) && (x.TransactionLock == null || x.TransactionLock.Equals(lockToken)), Builders<MongoDbRecord>.Update .Set(x => x.TransactionLock, lockToken) ); if (res == null) { var e = new ConcurrentMutationException(r); e.Data["ExceptionType"] = "LockRecord"; throw e; } #if DEBUG Logger.LogDebug($"Locked token {new ByteString(lockToken)} {r.Key.ToString()}"); #endif return res; } return null; }