Nhibernate 如何管理子事务或嵌套事务?

Nhibernate 如何管理子事务或嵌套事务?,nhibernate,Nhibernate,我想要一些类似子事务的东西,因为你可以标记一个开始子事务的点,然后在该位的描述点,你可以回滚(中止子位)或者在out transaction提交时进行有效的提交。当然,如果您中止外部事务,则标记位也将中止 如何使用NHibernate实现这一点,但事务在第一次提交期间被关闭,因此我收到了错误消息 没有要提交的开放事务 我的代码如下: API.Data.Session session = API.Data.SessionManager.GetSession(); session.B

我想要一些类似子事务的东西,因为你可以标记一个开始子事务的点,然后在该位的描述点,你可以回滚(中止子位)或者在out transaction提交时进行有效的提交。当然,如果您中止外部事务,则标记位也将中止

如何使用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;
         }


不能,NHibernate不支持嵌套事务。您可以通过Systems.Transaction命名空间实现这一点


编辑:可延迟事务实现如下所示。我将此作为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();
        }
    }
}
//
///开始事务或遵从现有事务。隔离级别将不会更改
///在现有事务上。
/// 
公共类可延迟事务:IDisposable
{
私人只读文件拥有的交易;
私有只读ITransaction\u事务;
公共延迟事务(ISession会话)
:此(会话,IsolationLevel.ReadCommitted)
{}
公共可延迟事务(ISession会话,IsolationLevel IsolationLevel)
{
if(session.Transaction.IsActive)
{
_ownedTransaction=false;
_事务=会话.transaction;
}
其他的
{
_ownedTransaction=true;
_事务=session.BeginTransaction(isolationLevel);
}
}
公有交易
{
获取{return\u ownedTransaction;}
}
公共无效委员会()
{
如果(_ownedTransaction)
{
_Commit();
}
}
public void RollbackOrDefer()
{
如果(_ownedTransaction)
{
_transaction.Rollback();
}
}
公共无效登记(IDbCommand)
{
_事务登记(命令);
}
公共福利活动
{
获取{return\u transaction.IsActive;}
}
公共场所被破坏了
{
获取{return\u transaction.WasCommitted;}
}
公共布尔值被回滚
{
获取{return\u transaction.wasrollledback;}
}
公共空间处置()
{
如果(_ownedTransaction)
{
_transaction.Dispose();
}
}
}

本机支持通过嵌套事务和
TransactionScope
类提供。请注意,Sql Server和Oracle支持AFAIK,但如果其他数据库支持分布式事务以及插入到System.Data的API,则它可能适用于其他数据库


看看这些问题,

难道没有其他方法吗?我不想直接与数据库交互不,没有其他方法。我根本不使用NHibernate将事务放在存储库/服务方法中,这样多个存储库方法就可以参与同一事务。在分布式系统之外很少需要嵌套事务。我有一个ISession的扩展方法,名为DeferrableTransaction,它使用类似的语义,允许事务延迟到现有事务或启动新事务。如果你有兴趣,我会贴出来。我不能代表OP发言,但我有兴趣看看你的impl
/// <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();
        }
    }
}