Как управлять вложенными транзакциями или вложенными транзакциями? - PullRequest
0 голосов
/ 20 июля 2010

Я хочу иметь что-то вроде субтранзакций, в которых вы можете пометить точку, в которой вы бы начали субтранзакцию, а затем в точке принятия решения для этого бита вы можете выполнить откат (прервать суб-транзакцию).бит) или продолжайте, эффективно совершая, когда завершает исходящий переход.Конечно, если вы прерываете внешнюю транзакцию, отмеченный бит также прерывается.

Как я могу сделать это с NHibernate, но транзакция закрывается во время первого коммита, и поэтому у меня появляется сообщение об ошибке

нет открытых транзакций для фиксации

Мой код выглядит следующим образом:

API.Data.Session session = API.Data.SessionManager.GetSession();
        session.BeginTransaction();
         try
        {
            Project project = Project.Load(ID);
            ...........
            Save(project);
            .....................

           session.CommitTransaction();
        }
         catch
         {
             session.RollbackTransaction();
             throw;
         }

    public void save(Project project)
    {
Data.SessionManager.GetSession().BeginTransaction();
                try
                {
                    Save();
                    LogIssueChange(test);
                    Data.SessionManager.GetSession().CommitTransaction();
                }
                catch
                {
                    Data.SessionManager.GetSession().RollbackTransaction();
                    throw;
                }
    }

Ответы [ 2 ]

1 голос
/ 20 июля 2010

Встроенная поддержка предоставляется через вложенные транзакции и класс TransactionScope.Обратите внимание, что AFAIK поддерживает Sql Server и Oracle, хотя может работать и для других баз данных, если они поддерживают распределенные транзакции, а также поддерживает API, подключаемый к System.Data.

см. Эти вопросы SO https://stackoverflow.com/questions/tagged/nhibernate+transactionscope

1 голос
/ 20 июля 2010

Нельзя, NHibernate не поддерживает вложенные транзакции.Этого можно достичь с помощью пространства имен Systems.Transaction.


Редактировать: реализация DeferableTransaction приведена ниже.У меня есть это как метод расширения на ISession.Тем не менее, использование было очень редко.

Методы расширения:

    public static DeferableTransaction BeginOrDeferTransaction(this ISession session)
    {
        return new DeferableTransaction(session);
    }

    public static DeferableTransaction BeginOrDeferTransaction(this ISession session, IsolationLevel isolationLevel)
    {
        return new DeferableTransaction(session, isolationLevel);
    }

Реализация:

/// <summary>
/// Begins a transaction or defers to an existing transaction. The IsolationLevel will not be changed
/// on an existing transaction.
/// </summary>
public class DeferableTransaction : IDisposable
{
    private readonly bool _ownedTransaction;
    private readonly ITransaction _transaction;

    public DeferableTransaction(ISession session) 
        : this(session, IsolationLevel.ReadCommitted)
    {}

    public DeferableTransaction(ISession session, IsolationLevel isolationLevel)
    {
        if (session.Transaction.IsActive)
        {
            _ownedTransaction = false;
            _transaction = session.Transaction;
        }
        else
        {
            _ownedTransaction = true;
            _transaction = session.BeginTransaction(isolationLevel);
        }
    }

    public bool OwnedTransaction
    {
        get { return _ownedTransaction; }
    }

    public void CommitOrDefer()
    {
        if (_ownedTransaction)
        {
            _transaction.Commit();
        }
    }

    public void RollbackOrDefer()
    {
        if (_ownedTransaction)
        {
            _transaction.Rollback();
        }
    }

    public void Enlist(IDbCommand command)
    {
        _transaction.Enlist(command);
    }

    public bool IsActive
    {
        get { return _transaction.IsActive; }
    }

    public bool WasCommitted
    {
        get { return _transaction.WasCommitted; }
    }

    public bool WasRolledBack
    {
        get { return _transaction.WasRolledBack; }
    }

    public void Dispose()
    {
        if (_ownedTransaction)
        {
            _transaction.Dispose();
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...