使用Nhibernate静默插入失败

时间:2016-04-15 15:52:48

标签: c# nhibernate fluent-nhibernate

我的插入NHibernate有问题

交易开始顺利, 我的选择正确完成, 我也从序列中选择下一个值, 并提交交易, 但是我的NHprofiler中没有出现插入,也没有出现错误。 我使用Session.OpenSession(ReadCommited)&交易 知道会发生什么事吗?

代码

class NHUnitOfWok : INHibernateUnitOfWork
{
    private readonly ISession _session;
    private bool _isDisposed;
    private IsolationLevel _isolationLevel;

    public NHUnitOfWok(ISession session)
    {
        _session = session;
        _session.FlushMode = FlushMode.Never;
        _isolationLevel = IsolationLevel.ReadCommitted;
    }

    internal ISession Session
    {
        get { return _session; }
    }

    public void SaveChanges()
    {
        Session.Flush();
    }

    public void CancelChanges()
    {
        Session.Clear();
    }

    public void Commit()
    {
        Session.Transaction.Commit();
    }

    public void Rollback()
    {
        Session.Transaction.Rollback();
    }


    public void WithinNewSession(Action<ISession> actionToExecute, IsolationLevel? isolationLevel = null)
    {
        using (var tempSession = Session.SessionFactory.OpenSession())
        {
            using (var transaction = tempSession.BeginTransaction(isolationLevel ?? _isolationLevel))
            {
                actionToExecute(tempSession);
                transaction.Commit();
            }
        }
    }

    public void WithinTransaction(Action action, IsolationLevel? isolationLevel = null)
    {
        Enforce.NotNull(action, "action");

        WithinTransaction<object>(() =>
        {
            action();
            return null;
        });
    }

    public T WithinTransaction<T>(Func<T> func, IsolationLevel? isolationLevel = null)
    {
        Enforce.NotNull(func, "func");

        if (Session.Transaction != null && Session.Transaction.IsActive)
        {
            return func.Invoke();
        }

        using (var localTran = Session.BeginTransaction(isolationLevel ?? _isolationLevel))
        {
            try
            {
                var funcRes = func.Invoke();
                localTran.Commit();

                return funcRes;
            }
            catch (TransactionException ex)
            {
                throw new DataException(Resource.TransactionException, ex);
            }
            catch (Exception ex)
            {
                if (Session.Transaction.IsActive)
                    localTran.Rollback();
                throw new DataException(Resource.TransactionException, ex);
            }
        }
    }

    public bool IsStarted()
    {
        return Session.Transaction != null && Session.Transaction.IsActive;
    }

    public void Start()
    {
        if (Session.Transaction == null || !Session.Transaction.IsActive)
        {
            Session.BeginTransaction(_isolationLevel);
        }
    }

    private void Dispose(bool disposing)
    {
        if (!disposing || _isDisposed)
        {
            return;
        }
        _isDisposed = true;
    }

    #region IDisposable Members

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    #endregion
}

1 个答案:

答案 0 :(得分:3)

FlushMode.Never可能对只读事务有好处,但对于其他任何事情,好吧,可能不是。它的xml文档说明:

  

除非应用程序显式调用ISession,否则永远不会刷新Flush()。此模式对于只读事务非常有效。

所以默认情况下不要使用它 至少这是我的建议。我知道有一些建议潜伏在“性能”原因使用它,但通过评论来检查你是否还有问题。
无论如何,我从来没有优先考虑运行时性能,开发人员的表现应该是我认为的优先事项。 (除非应用程序具有实际的,经证实的和相应的运行时性能问题。或者,当然,当代码在运行时执行复杂性方面是明显的编码恐怖时,例如无动机的O(n²)算法或最差的。)

如果您想坚持使用该模式,请在提交交易之前在会话上调用Flush(或按照here by Andrew编写,选择FlushMode.Commit)。但实际上,这种选择是开发人员不得不使用它的陷阱。

请参阅默认模式文档Auto

  

ISession有时在查询执行之前被刷新,以确保查询永远不会返回失效状态。这是默认的刷新模式。

您是否愿意承担由于在某些数据更改后在同一会话中发生的查询中出现意外陈旧数据而导致出现细微错误的风险?

旁注:为什么要将代码与Invoke“复杂化”?请参阅this