public void UpdateWithTransitional()
    {
        var endpointName = nameof(UpdateWithTransitional);
        var definition   = new SagaDefinition(
            tableSuffix: "CorrAndTransitionalSaga",
            name: "CorrAndTransitionalSaga",
            correlationProperty: new CorrelationProperty
            (
                name: "CorrelationProperty",
                type: CorrelationPropertyType.String
            ),
            transitionalCorrelationProperty: new CorrelationProperty
            (
                name: "TransitionalCorrelationProperty",
                type: CorrelationPropertyType.String
            )
            );

        DropAndCreate(definition, endpointName, schema);
        var id        = Guid.NewGuid();
        var sagaData1 = new CorrAndTransitionalSaga.SagaData
        {
            Id = id,
            CorrelationProperty             = "theCorrelationProperty",
            TransitionalCorrelationProperty = "theTransitionalCorrelationProperty",
            OriginalMessageId = "theOriginalMessageId",
            Originator        = "theOriginator",
            SimpleProperty    = "PropertyValue"
        };

        var persister = SetUp(endpointName, schema);

        using (var connection = dbConnection())
            using (var transaction = connection.BeginTransaction())
                using (var storageSession = new StorageSession(connection, transaction, true, null))
                {
                    persister.Save(sagaData1, storageSession, "theProperty").GetAwaiter().GetResult();
                    storageSession.CompleteAsync().GetAwaiter().GetResult();
                }

        using (var connection = dbConnection())
            using (var transaction = connection.BeginTransaction())
                using (var storageSession = new StorageSession(connection, transaction, true, null))
                {
                    var sagaData = persister.Get <CorrAndTransitionalSaga.SagaData>(id, storageSession).GetAwaiter().GetResult();
                    sagaData.Data.SimpleProperty = "UpdatedValue";
                    persister.Update(sagaData.Data, storageSession, sagaData.Version).GetAwaiter().GetResult();
                    storageSession.CompleteAsync().GetAwaiter().GetResult();
                }

        using (var connection = dbConnection())
            using (var transaction = connection.BeginTransaction())
                using (var storageSession = new StorageSession(connection, transaction, true, null))
                {
                    var sagaData = persister.Get <CorrAndTransitionalSaga.SagaData>(id, storageSession).GetAwaiter().GetResult();
                    Assert.IsNotNull(sagaData);
                    Approver.Verify(sagaData, s => s.Replace(id.ToString(), "theSagaId"));
                    Assert.AreEqual(2, sagaData.Version);
                }
    }
        public async Task CompleteAsync_completes_transaction()
        {
            var dictionary = await session.StateManager.GetOrAddAsync <IReliableDictionary <string, string> >("test", TimeSpan.FromSeconds(5));

            await dictionary.AddAsync(session.Transaction, "Key", "Value");

            await session.CompleteAsync();

            using (var tx = stateManager.CreateTransaction())
            {
                var value = await dictionary.TryGetValueAsync(tx, "Key");

                Assert.True(value.HasValue);
                Assert.AreEqual("Value", value.Value);
            }
        }
    public async Task CallbackThrows()
    {
        var exceptionThrown = false;
        var id       = Guid.NewGuid();
        var sagaData = new SagaWithCorrelation.SagaData
        {
            Id = id,
            OriginalMessageId   = "theOriginalMessageId",
            Originator          = "theOriginator",
            SimpleProperty      = "PropertyValue",
            CorrelationProperty = "theCorrelationProperty"
        };

        var persister  = SetUp(nameof(CallbackThrows), schema);
        var definition = new SagaDefinition(
            tableSuffix: "SagaWithCorrelation",
            name: "SagaWithCorrelation",
            correlationProperty: new CorrelationProperty
            (
                name: "CorrelationProperty",
                type: CorrelationPropertyType.String
            )
            );

        DropAndCreate(definition, nameof(CallbackThrows), schema);

        using (var connection = dbConnection())
            using (var transaction = connection.BeginTransaction())
                using (var storageSession = new StorageSession(connection, transaction, true, null))
                {
                    await persister.Save(sagaData, storageSession, "theProperty").ConfigureAwait(false);

                    storageSession.OnSaveChanges(s =>
                    {
                        throw new Exception("Simulated");
                    });
                    try
                    {
                        await storageSession.CompleteAsync();
                    }
                    catch (Exception)
                    {
                        exceptionThrown = true;
                    }
                }

        Assert.IsTrue(exceptionThrown);

        using (var connection = dbConnection())
            using (var transaction = connection.BeginTransaction())
                using (var storageSession = new StorageSession(connection, transaction, true, null))
                {
                    var savedEntity = await persister.Get <SagaWithCorrelation.SagaData>(id, storageSession).ConfigureAwait(false);

                    Assert.IsNull(savedEntity.Data);
                }
    }
    public async Task SaveDuplicateShouldThrow()
    {
        var endpointName = nameof(SaveDuplicateShouldThrow);

        var definition = new SagaDefinition(
            tableSuffix: "SagaWithCorrelation",
            name: "SagaWithCorrelation",
            correlationProperty: new CorrelationProperty
            (
                name: "CorrelationProperty",
                type: CorrelationPropertyType.String
            )
            );

        DropAndCreate(definition, endpointName, schema);
        var persister = SetUp(endpointName, schema);

        using (var connection = dbConnection())
            using (var transaction = connection.BeginTransaction())
                using (var storageSession = new StorageSession(connection, transaction, true, null))
                {
                    var data = new SagaWithCorrelation.SagaData
                    {
                        Id = Guid.NewGuid(),
                        OriginalMessageId   = "theOriginalMessageId",
                        Originator          = "theOriginator",
                        CorrelationProperty = "theCorrelationProperty",
                        SimpleProperty      = "theSimpleProperty"
                    };
                    await persister.Save(data, storageSession, "theCorrelationProperty").ConfigureAwait(false);

                    await storageSession.CompleteAsync().ConfigureAwait(false);
                }
        using (var connection = dbConnection())
            using (var transaction = connection.BeginTransaction())
                using (var storageSession = new StorageSession(connection, transaction, true, null))
                {
                    var data = new SagaWithCorrelation.SagaData
                    {
                        Id = Guid.NewGuid(),
                        OriginalMessageId   = "theOriginalMessageId",
                        Originator          = "theOriginator",
                        CorrelationProperty = "theCorrelationProperty",
                        SimpleProperty      = "theSimpleProperty"
                    };
                    var throwsAsync = Assert.ThrowsAsync <Exception>(async() =>
                    {
                        await persister.Save(data, storageSession, "theCorrelationProperty").ConfigureAwait(false);
                        await storageSession.CompleteAsync().ConfigureAwait(false);
                    });
                    var innerException = throwsAsync.InnerException;
                    Assert.IsTrue(IsConcurrencyException(innerException));
                }
    }
    public async Task UpdateWithWrongVersion()
    {
        var wrongVersion = 666;
        var endpointName = nameof(UpdateWithWrongVersion);

        var definition = new SagaDefinition(
            tableSuffix: "SagaWithCorrelation",
            name: "SagaWithCorrelation",
            correlationProperty: new CorrelationProperty
            (
                name: "CorrelationProperty",
                type: CorrelationPropertyType.String
            )
            );

        DropAndCreate(definition, endpointName, schema);
        var id        = Guid.NewGuid();
        var sagaData1 = new SagaWithCorrelation.SagaData
        {
            Id = id,
            OriginalMessageId = "theOriginalMessageId",
            Originator        = "theOriginator",
            SimpleProperty    = "PropertyValue"
        };

        var persister = SetUp(endpointName, schema);

        using (var connection = dbConnection())
            using (var transaction = connection.BeginTransaction())
                using (var storageSession = new StorageSession(connection, transaction, true, null))
                {
                    await persister.Save(sagaData1, storageSession, "theProperty").ConfigureAwait(false);

                    await storageSession.CompleteAsync().ConfigureAwait(false);
                }

        using (var connection = dbConnection())
            using (var transaction = connection.BeginTransaction())
                using (var storageSession = new StorageSession(connection, transaction, true, null))
                {
                    var sagaData = await persister.Get <SagaWithCorrelation.SagaData>(id, storageSession).ConfigureAwait(false);

                    sagaData.Data.SimpleProperty = "UpdatedValue";

                    var exception = Assert.ThrowsAsync <Exception>(() => persister.Update(sagaData.Data, storageSession, wrongVersion));
                    Assert.IsTrue(exception.Message.Contains("Optimistic concurrency violation"));
                }
    }
    public async Task CallbackIsInvoked()
    {
        var callbackInvoked = false;

        using (var connection = dbConnection())
            using (var transaction = connection.BeginTransaction())
                using (var storageSession = new StorageSession(connection, transaction, true, null))
                {
                    storageSession.OnSaveChanges(s =>
                    {
                        callbackInvoked = true;
                        return(Task.FromResult(0));
                    });
                    await storageSession.CompleteAsync();
                }
        Assert.IsTrue(callbackInvoked);
    }