public async Task Save_fails_when_data_changes_between_read_and_update_on_same_thread() { var sagaId = Guid.NewGuid(); var saga = new TestSagaData { Id = sagaId, SomeId = sagaId.ToString() }; var persister = new InMemorySagaPersister(); var insertSession = new InMemorySynchronizedStorageSession(); await persister.Save(saga, SagaMetadataHelper.GetMetadata<TestSaga>(saga), insertSession, new ContextBag()); await insertSession.CompleteAsync(); var winningContext = new ContextBag(); var record = await persister.Get<TestSagaData>(saga.Id, new InMemorySynchronizedStorageSession(), winningContext); var losingContext = new ContextBag(); var staleRecord = await persister.Get<TestSagaData>("SomeId", sagaId.ToString(), new InMemorySynchronizedStorageSession(), losingContext); var winningSaveSession = new InMemorySynchronizedStorageSession(); var losingSaveSession = new InMemorySynchronizedStorageSession(); await persister.Update(record, winningSaveSession, winningContext); await persister.Update(staleRecord, losingSaveSession, losingContext); await winningSaveSession.CompleteAsync(); Assert.That(async () => await losingSaveSession.CompleteAsync(), Throws.InstanceOf<Exception>().And.Message.StartsWith($"InMemorySagaPersister concurrency violation: saga entity Id[{saga.Id}] already saved.")); }
public async Task Save_fails_when_writing_same_data_twice() { var saga = new TestSagaData { Id = Guid.NewGuid() }; var persister = new InMemorySagaPersister(); var insertSession = new InMemorySynchronizedStorageSession(); await persister.Save(saga, SagaMetadataHelper.GetMetadata <TestSaga>(saga), insertSession, new ContextBag()); await insertSession.CompleteAsync(); var retrievingContext = new ContextBag(); var returnedSaga1 = await persister.Get <TestSagaData>(saga.Id, new InMemorySynchronizedStorageSession(), retrievingContext); var winningSaveSession = new InMemorySynchronizedStorageSession(); var losingSaveSession = new InMemorySynchronizedStorageSession(); await persister.Update(returnedSaga1, winningSaveSession, retrievingContext); await persister.Update(returnedSaga1, losingSaveSession, retrievingContext); await winningSaveSession.CompleteAsync(); Assert.That(async() => await losingSaveSession.CompleteAsync(), Throws.InstanceOf <Exception>().And.Message.StartsWith($"InMemorySagaPersister concurrency violation: saga entity Id[{saga.Id}] already saved.")); }
public async Task Save_fails_when_data_changes_between_read_and_update_on_same_thread() { var sagaId = Guid.NewGuid(); var saga = new TestSagaData { Id = sagaId, SomeId = sagaId.ToString() }; var persister = new InMemorySagaPersister(); var insertSession = new InMemorySynchronizedStorageSession(); await persister.Save(saga, SagaMetadataHelper.GetMetadata <TestSaga>(saga), insertSession, new ContextBag()); await insertSession.CompleteAsync(); var winningContext = new ContextBag(); var record = await persister.Get <TestSagaData>(saga.Id, new InMemorySynchronizedStorageSession(), winningContext); var losingContext = new ContextBag(); var staleRecord = await persister.Get <TestSagaData>("SomeId", sagaId.ToString(), new InMemorySynchronizedStorageSession(), losingContext); var winningSaveSession = new InMemorySynchronizedStorageSession(); var losingSaveSession = new InMemorySynchronizedStorageSession(); await persister.Update(record, winningSaveSession, winningContext); await persister.Update(staleRecord, losingSaveSession, losingContext); await winningSaveSession.CompleteAsync(); Assert.That(async() => await losingSaveSession.CompleteAsync(), Throws.InstanceOf <Exception>().And.Message.StartsWith($"InMemorySagaPersister concurrency violation: saga entity Id[{saga.Id}] already saved.")); }
public async Task Save_process_is_repeatable() { var sagaId = Guid.NewGuid(); var saga = new TestSagaData { Id = sagaId, SomeId = sagaId.ToString() }; var persister = new InMemorySagaPersister(); var insertSession = new InMemorySynchronizedStorageSession(); await persister.Save(saga, SagaMetadataHelper.GetMetadata <TestSaga>(saga), insertSession, new ContextBag()); await insertSession.CompleteAsync(); var winningSessionContext = new ContextBag(); var returnedSaga1 = await Task.Run(() => persister.Get <TestSagaData>(saga.Id, new InMemorySynchronizedStorageSession(), winningSessionContext)); var losingSessionContext = new ContextBag(); var returnedSaga2 = await persister.Get <TestSagaData>("SomeId", sagaId.ToString(), new InMemorySynchronizedStorageSession(), losingSessionContext); var winningSaveSession = new InMemorySynchronizedStorageSession(); var losingSaveSession = new InMemorySynchronizedStorageSession(); await persister.Update(returnedSaga1, winningSaveSession, winningSessionContext); await persister.Update(returnedSaga2, losingSaveSession, losingSessionContext); await winningSaveSession.CompleteAsync(); Assert.That(async() => await losingSaveSession.CompleteAsync(), Throws.InstanceOf <Exception>().And.Message.StartsWith($"InMemorySagaPersister concurrency violation: saga entity Id[{saga.Id}] already saved.")); losingSessionContext = new ContextBag(); var returnedSaga3 = await Task.Run(() => persister.Get <TestSagaData>("SomeId", sagaId.ToString(), new InMemorySynchronizedStorageSession(), losingSessionContext)); winningSessionContext = new ContextBag(); var returnedSaga4 = await persister.Get <TestSagaData>(saga.Id, new InMemorySynchronizedStorageSession(), winningSessionContext); winningSaveSession = new InMemorySynchronizedStorageSession(); losingSaveSession = new InMemorySynchronizedStorageSession(); await persister.Update(returnedSaga4, winningSaveSession, winningSessionContext); await persister.Update(returnedSaga3, losingSaveSession, losingSessionContext); await winningSaveSession.CompleteAsync(); Assert.That(async() => await losingSaveSession.CompleteAsync(), Throws.InstanceOf <Exception>().And.Message.StartsWith($"InMemorySagaPersister concurrency violation: saga entity Id[{saga.Id}] already saved.")); }
public async Task It_should_successfully_update_the_saga() { var id = Guid.NewGuid(); var sagaData = new SagaWithoutUniquePropertyData { Id = id, NonUniqueString = "whatever" }; var persister = new InMemorySagaPersister(); // first session var session = new InMemorySynchronizedStorageSession(); await persister.Save(sagaData, SagaCorrelationProperty.None, session, new ContextBag()); await session.CompleteAsync(); // second session var session2 = new InMemorySynchronizedStorageSession(); var ctx = new ContextBag(); var saga = await persister.Get <SagaWithoutUniquePropertyData>(id, session2, ctx); saga.NonUniqueString = "asdfasdf"; await persister.Update(saga, session2, ctx); await session2.CompleteAsync(); var result = await persister.Get <SagaWithoutUniquePropertyData>(sagaData.Id, new InMemorySynchronizedStorageSession(), new ContextBag()); Assert.That(result, Is.Not.Null); Assert.That(result.NonUniqueString, Is.EqualTo("asdfasdf")); }
public async Task It_should_successfully_update_the_saga() { var id = Guid.NewGuid(); var sagaData = new SagaWithoutUniquePropertyData { Id = id, NonUniqueString = "whatever" }; var persister = new InMemorySagaPersister(); // first session var session = new InMemorySynchronizedStorageSession(); await persister.Save(sagaData, SagaCorrelationProperty.None, session, new ContextBag()); await session.CompleteAsync(); // second session var session2 = new InMemorySynchronizedStorageSession(); var ctx = new ContextBag(); var saga = await persister.Get<SagaWithoutUniquePropertyData>(id, session2, ctx); saga.NonUniqueString = "asdfasdf"; await persister.Update(saga, session2, ctx); await session2.CompleteAsync(); var result = await persister.Get<SagaWithoutUniquePropertyData>(sagaData.Id, new InMemorySynchronizedStorageSession(), new ContextBag()); Assert.That(result, Is.Not.Null); Assert.That(result.NonUniqueString, Is.EqualTo("asdfasdf")); }
public async Task It_should_persist_successfully() { var saga1 = new SagaWithUniquePropertyData { Id = Guid.NewGuid(), UniqueString = "whatever" }; var saga2 = new SagaWithUniquePropertyData { Id = Guid.NewGuid(), UniqueString = "whatever" }; var persister = new InMemorySagaPersister(); var firstInsertSession = new InMemorySynchronizedStorageSession(); await persister.Save(saga1, SagaMetadataHelper.GetMetadata <SagaWithUniqueProperty>(saga1), firstInsertSession, new ContextBag()); await firstInsertSession.CompleteAsync(); var updateSession = new InMemorySynchronizedStorageSession(); saga1 = await persister.Get <SagaWithUniquePropertyData>(saga1.Id, updateSession, new ContextBag()); saga1.UniqueString = "whatever2"; await persister.Update(saga1, updateSession, new ContextBag()); await updateSession.CompleteAsync(); var secondInsertSession = new InMemorySynchronizedStorageSession(); await persister.Save(saga2, SagaMetadataHelper.GetMetadata <SagaWithUniqueProperty>(saga2), secondInsertSession, new ContextBag()); await secondInsertSession.CompleteAsync(); }
public void It_should_persist_successfully() { var saga1 = new SagaWithUniqueProperty { Id = Guid.NewGuid(), UniqueString = "whatever"}; var inMemorySagaPersister = new InMemorySagaPersister() as ISagaPersister; inMemorySagaPersister.Save(saga1); saga1 = inMemorySagaPersister.Get<SagaWithUniqueProperty>(saga1.Id); inMemorySagaPersister.Update(saga1); }
public async Task Save_fails_when_data_changes_between_concurrent_instances() { var saga = new TestSagaData { Id = Guid.NewGuid() }; var persister = new InMemorySagaPersister(); var storageAdapter = new InMemoryTransactionalSynchronizedStorageAdapter(); var insertSession = new InMemorySynchronizedStorageSession(); await persister.Save(saga, SagaMetadataHelper.GetMetadata <TestSaga>(saga), insertSession, new ContextBag()); await insertSession.CompleteAsync(); Assert.That(async() => { using (var tx = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { Transaction.Current.EnlistDurable(EnlistmentWhichEnforcesDtcEscalation.Id, new EnlistmentWhichEnforcesDtcEscalation(), EnlistmentOptions.None); var transportTransaction = new TransportTransaction(); transportTransaction.Set(Transaction.Current); var unenlistedSession = new InMemorySynchronizedStorageSession(); var enlistedSession = await storageAdapter.TryAdapt(transportTransaction, new ContextBag()); var unenlistedSessionContext = new ContextBag(); var unenlistedRecord = await persister.Get <TestSagaData>(saga.Id, unenlistedSession, unenlistedSessionContext); var enlistedSessionContext = new ContextBag(); var enlistedRecord = await persister.Get <TestSagaData>("Id", saga.Id, enlistedSession, enlistedSessionContext); await persister.Update(unenlistedRecord, unenlistedSession, unenlistedSessionContext); await persister.Update(enlistedRecord, enlistedSession, enlistedSessionContext); await unenlistedSession.CompleteAsync(); tx.Complete(); } }, Throws.Exception.TypeOf <TransactionAbortedException>()); }
public async Task Save_fails_when_data_changes_between_concurrent_instances() { var saga = new TestSagaData { Id = Guid.NewGuid() }; var persister = new InMemorySagaPersister(); var storageAdapter = new InMemoryTransactionalSynchronizedStorageAdapter(); var insertSession = new InMemorySynchronizedStorageSession(); await persister.Save(saga, SagaMetadataHelper.GetMetadata<TestSaga>(saga), insertSession, new ContextBag()); await insertSession.CompleteAsync(); Assert.That(async () => { using (var tx = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { Transaction.Current.EnlistDurable(EnlistmentWhichEnforcesDtcEscalation.Id, new EnlistmentWhichEnforcesDtcEscalation(), EnlistmentOptions.None); var transportTransaction = new TransportTransaction(); transportTransaction.Set(Transaction.Current); var unenlistedSession = new InMemorySynchronizedStorageSession(); var enlistedSession = await storageAdapter.TryAdapt(transportTransaction, new ContextBag()); var unenlistedSessionContext = new ContextBag(); var unenlistedRecord = await persister.Get<TestSagaData>(saga.Id, unenlistedSession, unenlistedSessionContext); var enlistedSessionContext = new ContextBag(); var enlistedRecord = await persister.Get<TestSagaData>("Id", saga.Id, enlistedSession, enlistedSessionContext); await persister.Update(unenlistedRecord, unenlistedSession, unenlistedSessionContext); await persister.Update(enlistedRecord, enlistedSession, enlistedSessionContext); await unenlistedSession.CompleteAsync(); tx.Complete(); } }, Throws.Exception.TypeOf<TransactionAbortedException>()); }
public void It_should_persist_successfully() { var saga1 = new SagaWithUniqueProperty { Id = Guid.NewGuid(), UniqueString = "whatever" }; var inMemorySagaPersister = new InMemorySagaPersister() as ISagaPersister; inMemorySagaPersister.Save(saga1); saga1 = inMemorySagaPersister.Get <SagaWithUniqueProperty>(saga1.Id); inMemorySagaPersister.Update(saga1); }
public void It_should_persist_successfully() { var saga1 = new SagaWithUniqueProperty {Id = Guid.NewGuid(), UniqueString = "whatever1"}; var saga2 = new SagaWithUniqueProperty {Id = Guid.NewGuid(), UniqueString = "whatever"}; var inMemorySagaPersister = new InMemorySagaPersister() as ISagaPersister; inMemorySagaPersister.Save(saga1); inMemorySagaPersister.Save(saga2); Assert.Throws<InvalidOperationException>(() => { var saga = inMemorySagaPersister.Get<SagaWithUniqueProperty>(saga2.Id); saga.UniqueString = "whatever1"; inMemorySagaPersister.Update(saga); }); }
public void It_should_persist_successfully_for_two_unique_properties() { var saga1 = new SagaWithTwoUniqueProperties { Id = Guid.NewGuid(), UniqueString = "whatever1", UniqueInt = 5}; var saga2 = new SagaWithTwoUniqueProperties { Id = Guid.NewGuid(), UniqueString = "whatever", UniqueInt = 37}; var inMemorySagaPersister = new InMemorySagaPersister() as ISagaPersister; inMemorySagaPersister.Save(saga1); inMemorySagaPersister.Save(saga2); Assert.Throws<InvalidOperationException>(() => { var saga = inMemorySagaPersister.Get<SagaWithTwoUniqueProperties>(saga2.Id); saga.UniqueInt = 5; inMemorySagaPersister.Update(saga); }); }
public void It_should_persist_successfully_for_two_unique_properties() { var saga1 = new SagaWithTwoUniqueProperties { Id = Guid.NewGuid(), UniqueString = "whatever1", UniqueInt = 5 }; var saga2 = new SagaWithTwoUniqueProperties { Id = Guid.NewGuid(), UniqueString = "whatever", UniqueInt = 37 }; var inMemorySagaPersister = new InMemorySagaPersister() as ISagaPersister; inMemorySagaPersister.Save(saga1); inMemorySagaPersister.Save(saga2); Assert.Throws <InvalidOperationException>(() => { var saga = inMemorySagaPersister.Get <SagaWithTwoUniqueProperties>(saga2.Id); saga.UniqueInt = 5; inMemorySagaPersister.Update(saga); }); }
public async Task It_should_persist_successfully() { var saga1 = new SagaWithUniquePropertyData { Id = Guid.NewGuid(), UniqueString = "whatever" }; var persister = new InMemorySagaPersister(); var insertSession = new InMemorySynchronizedStorageSession(); await persister.Save(saga1, SagaMetadataHelper.GetMetadata<SagaWithUniqueProperty>(saga1), insertSession, new ContextBag()); await insertSession.CompleteAsync(); var updatingContext = new ContextBag(); saga1 = await persister.Get<SagaWithUniquePropertyData>(saga1.Id, new InMemorySynchronizedStorageSession(), updatingContext); var updateSession = new InMemorySynchronizedStorageSession(); await persister.Update(saga1, updateSession, updatingContext); await updateSession.CompleteAsync(); }
public void It_should_persist_successfully() { var saga1 = new SagaWithUniqueProperty { Id = Guid.NewGuid(), UniqueString = "whatever1" }; var saga2 = new SagaWithUniqueProperty { Id = Guid.NewGuid(), UniqueString = "whatever" }; var inMemorySagaPersister = new InMemorySagaPersister() as ISagaPersister; inMemorySagaPersister.Save(saga1); inMemorySagaPersister.Save(saga2); Assert.Throws <InvalidOperationException>(() => { var saga = inMemorySagaPersister.Get <SagaWithUniqueProperty>(saga2.Id); saga.UniqueString = "whatever1"; inMemorySagaPersister.Update(saga); }); }
public async Task Save_process_is_repeatable() { var sagaId = Guid.NewGuid(); var saga = new TestSagaData { Id = sagaId, SomeId = sagaId.ToString() }; var persister = new InMemorySagaPersister(); var insertSession = new InMemorySynchronizedStorageSession(); await persister.Save(saga, SagaMetadataHelper.GetMetadata<TestSaga>(saga), insertSession, new ContextBag()); await insertSession.CompleteAsync(); var winningSessionContext = new ContextBag(); var returnedSaga1 = await Task.Run(() => persister.Get<TestSagaData>(saga.Id, new InMemorySynchronizedStorageSession(), winningSessionContext)); var losingSessionContext = new ContextBag(); var returnedSaga2 = await persister.Get<TestSagaData>("SomeId", sagaId.ToString(), new InMemorySynchronizedStorageSession(), losingSessionContext); var winningSaveSession = new InMemorySynchronizedStorageSession(); var losingSaveSession = new InMemorySynchronizedStorageSession(); await persister.Update(returnedSaga1, winningSaveSession, winningSessionContext); await persister.Update(returnedSaga2, losingSaveSession, losingSessionContext); await winningSaveSession.CompleteAsync(); Assert.That(async () => await losingSaveSession.CompleteAsync(), Throws.InstanceOf<Exception>().And.Message.StartsWith($"InMemorySagaPersister concurrency violation: saga entity Id[{saga.Id}] already saved.")); losingSessionContext = new ContextBag(); var returnedSaga3 = await Task.Run(() => persister.Get<TestSagaData>("SomeId", sagaId.ToString(), new InMemorySynchronizedStorageSession(), losingSessionContext)); winningSessionContext = new ContextBag(); var returnedSaga4 = await persister.Get<TestSagaData>(saga.Id, new InMemorySynchronizedStorageSession(), winningSessionContext); winningSaveSession = new InMemorySynchronizedStorageSession(); losingSaveSession = new InMemorySynchronizedStorageSession(); await persister.Update(returnedSaga4, winningSaveSession, winningSessionContext); await persister.Update(returnedSaga3, losingSaveSession, losingSessionContext); await winningSaveSession.CompleteAsync(); Assert.That(async () => await losingSaveSession.CompleteAsync(), Throws.InstanceOf<Exception>().And.Message.StartsWith($"InMemorySagaPersister concurrency violation: saga entity Id[{saga.Id}] already saved.")); }
public void Update(ISagaData sagaData, string[] sagaDataPropertyPathsToIndex) { innerPersister.Update(sagaData, sagaDataPropertyPathsToIndex); }
public async Task Save_fails_when_writing_same_data_twice() { var saga = new TestSagaData { Id = Guid.NewGuid() }; var persister = new InMemorySagaPersister(); var insertSession = new InMemorySynchronizedStorageSession(); await persister.Save(saga, SagaMetadataHelper.GetMetadata<TestSaga>(saga), insertSession, new ContextBag()); await insertSession.CompleteAsync(); var retrievingContext = new ContextBag(); var returnedSaga1 = await persister.Get<TestSagaData>(saga.Id, new InMemorySynchronizedStorageSession(), retrievingContext); var winningSaveSession = new InMemorySynchronizedStorageSession(); var losingSaveSession = new InMemorySynchronizedStorageSession(); await persister.Update(returnedSaga1, winningSaveSession, retrievingContext); await persister.Update(returnedSaga1, losingSaveSession, retrievingContext); await winningSaveSession.CompleteAsync(); Assert.That(async () => await losingSaveSession.CompleteAsync(), Throws.InstanceOf<Exception>().And.Message.StartsWith($"InMemorySagaPersister concurrency violation: saga entity Id[{saga.Id}] already saved.")); }