我只是在学习 nHibernate,并且遇到了一个可能很容易解决的问题。
是的,到目前为止,我已经发现您不能/不应该将 nHibernate 事务嵌套在彼此之间;就我而言,当范围转到另一个例程并开始新事务时,我发现了这一点。
那么我应该做以下事情吗?
using (ITransaction transaction = session.BeginTransaction())
{
NHibernateMembership mQuery =
session.QueryOver<NHibernateMembership>()
.Where(x => x.Username == username)
.And(x => x.ApplicationName == ApplicationName)
.SingleOrDefault();
if (mQuery != null)
{
mQuery.PasswordQuestion = newPwdQuestion;
mQuery.PasswordAnswer = EncodePassword(newPwdAnswer);
session.Update(mQuery);
transaction.Commit();
passwordQuestionUpdated = true;
}
}
// Assume this is in another routine elsewhere but being
// called right after the first in the same request
using (ITransaction transaction = session.BeginTransaction())
{
NHibernateMembership mQuery =
session.QueryOver<NHibernateMembership>()
.Where(x => x.Username == username)
.And(x => x.ApplicationName == ApplicationName)
.SingleOrDefault();
if (mQuery != null)
{
mQuery.PasswordQuestion = newPwdQuestion;
mQuery.PasswordAnswer = EncodePassword(newPwdAnswer);
session.Update(mQuery);
transaction.Commit();
passwordQuestionUpdated = true;
}
}
注意:我知道它们只是一个副本,我只是在展示我的问题
第一个问题 这是它应该做的方式吗?每个操作的交易?
第二个问题 我需要调用 transaction.Commit(); 每次还是只在最后一组?
第三个问题 有没有更好的方法,自动或手动,来做到这一点?
第三个问题 我可以使用 session.Transaction.IsActive 来确定“当前会话”是否已经是事务的一部分 - 所以在这种情况下,我可以在最高级别进行“事务包装”,比如说 Web 表单代码,以及让例程在其中调用,然后在最后提交所有工作。这是一个有缺陷的方法吗?
我真的很想把它敲下来,所以我按我的意思开始;我不想找到 1000 行代码,因为我需要全部更改。
提前致谢。
编辑:
对,所以我写了一些代码来准确解释我的问题。
private void CallingRoutine()
{
using(ISession session = Helper.GetCurrentSession)
{
using (ITransaction transaction = session.BeginTransaction())
{
// RUN nHIbernate QUERY to get an OBJECT-1
// DO WORK on OBJECT
// Need to CALL an EXTERNAL ROUTINE to finish work
ExternalRoutine();
// DO WORK on OBJECT-1 again
// *** At this point ADO exception triggers
}
}
}
private bool ExternalRoutine()
{
using(ISession session = Helper.GetCurrentSession)
{
using (ITransaction transaction = session.BeginTransaction())
{
// RUN nHIbernate QUERY to get an OBJECT-2
// DO WORK on OBJECT
// Determine result
if(Data)
{
return true;
}
return false;
}
}
}
希望这能说明问题。这就是我理解编写事务的方式,但请注意 ADO 异常是如何发生的。我显然做错了什么。我打算如何编写这些例程?
例如,如果我要为某个提供程序编写一个辅助对象,并且在每个公开的例程中都有一个 nHibernate 查询运行——假设我对调用函数和数据一无所知,我将如何编写这些例程,关于事务——我的工作是有效和高效地使用 nHibernate 并返回结果。
这就是我通过编写事务我在 ExternalRoutine() 中所做的假设 - 假设这是 nHibernate 的唯一用途并明确地进行事务。