我插入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
}
最佳答案
FlushMode.Never
可能对只读事务很有用,但对于其他任何事情,可能不是。它的xml文档指出:
除非应用程序显式调用ISession
,否则永远不会刷新Flush()
。此模式对于只读事务非常有效。
因此,默认情况下不要使用它。
至少这是我的建议。我知道有一些建议会出于“性能”的原因而使用它,但是请通过注释一下来检查是否还有问题。
无论如何,我从来没有首先针对运行时性能进行过优化,我认为开发人员的性能应该是首要任务。 (除非应用程序存在实际的,经过验证的和相应的运行时性能问题。或者,当然,从运行时执行复杂性的角度来看,代码是明显的编码恐怖,例如动机不佳的O(n²)算法或最糟糕的情况。)
如果要坚持使用该模式,请在提交事务之前在会话上调用Flush
(或按照here by Andrew的说明选择FlushMode.Commit
)。但是,实际上,这种选择是开发人员必须使用它的陷阱。
请参阅默认模式文档Auto
:
有时会在执行查询之前刷新ISession
,以确保查询永远不会返回陈旧状态。这是默认的刷新模式。
您是否愿意冒险由于某些数据更改后在同一会话中发生的查询中意外地获取过时的数据而遇到细微的错误?
旁注:为什么将Invoke
代码“复杂化”?请参见this。
关于c# - 使用Nhibernate静默插入失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36651678/