예제 #1
0
        public override void Prepare(string id)
        {
            EsentTransactionContext context;

            if (transactionContexts.TryGetValue(id, out context) == false)
            {
                var myContext = CreateEsentTransactionContext();
                try
                {
                    context = transactionContexts.GetOrAdd(id, myContext);
                }
                finally
                {
                    if (myContext != context)
                    {
                        myContext.Dispose();
                    }
                }
            }
            try
            {
                using (storage.SetTransactionContext(context))
                {
                    storage.Batch(accessor => RunOperationsInTransaction(id));
                }
            }
            catch (Exception)
            {
                Rollback(id);
                throw;
            }
        }
예제 #2
0
        public override void Prepare(string id, Guid?resourceManagerId, byte[] recoveryInformation)
        {
            try
            {
                EsentTransactionContext context;
                if (transactionContexts.TryGetValue(id, out context) == false)
                {
                    var myContext = CreateEsentTransactionContext();
                    try
                    {
                        context = transactionContexts.GetOrAdd(id, myContext);
                    }
                    finally
                    {
                        if (myContext != context)
                        {
                            myContext.Dispose();
                        }
                    }
                }

                List <DocumentInTransactionData> changes = null;
                using (storage.SetTransactionContext(context))
                {
                    storage.Batch(accessor =>
                    {
                        var itemsToTouch     = RunOperationsInTransaction(id, out changes);
                        context.ItemsToTouch = itemsToTouch;
                    });
                }

                if (changes == null)
                {
                    return;
                }

                // independent storage transaction, will actually commit here
                storage.Batch(accessor =>
                {
                    var jsonSerializer = JsonExtensions.CreateDefaultJsonSerializer();
                    var data           = new RavenJObject
                    {
                        {
                            "Changes",
                            RavenJToken.FromObject(changes, jsonSerializer)
                        },
                        { "ResourceManagerId", resourceManagerId.ToString() }, { "RecoveryInformation", recoveryInformation }
                    };
                    accessor.Lists.Set("Raven/Transactions/Pending", id, data, UuidType.DocumentTransactions);
                });
            }
            catch (Exception)
            {
                Rollback(id);
                throw;
            }
        }
        public override void Commit(string id)
        {
            EsentTransactionContext context;

            if (transactionContexts.TryGetValue(id, out context) == false)
            {
                throw new InvalidOperationException("There is no transaction with id: " + id + " ready to commit. Did you call PrepareTransaction?");
            }

            lock (context)
            {
                //using(context.Session) - disposing the session is actually done in the rollback, which is always called
                using (context.EnterSessionContext())
                {
                    if (context.DocumentIdsToTouch != null)
                    {
                        using (storage.SetTransactionContext(context))
                        {
                            storage.Batch(accessor =>
                            {
                                foreach (var docId in context.DocumentIdsToTouch)
                                {
                                    _database.Indexes.CheckReferenceBecauseOfDocumentUpdate(docId, accessor);

                                    Etag preTouchEtag;
                                    Etag afterTouchEtag;
                                    accessor.Documents.TouchDocument(docId, out preTouchEtag, out afterTouchEtag);
                                }
                            });
                        }
                    }

                    context.Transaction.Commit(txMode);

                    foreach (var afterCommit in context.ActionsAfterCommit)
                    {
                        afterCommit();
                    }
                }
            }
        }