在活动事务中执行Flush()

时间:2010-09-14 18:22:40

标签: nhibernate transactions flush

我有一个我经常遇到的情景。这很简单 标准的ADO交易,但不是NH(我知道)。

我有2个表要更新。第一个包含个人资料信息 (配置文件)和其他(工作)包含需要的记录更改 制作和这些变化的状态。对于每次更新 配置文件表,将对工作状态进行更新 表

  • 如果对Profile表的更新失败,我需要更新 工作表上的状态。
  • 如果对Profile表的更新成功,则更新到 工作表失败,我需要回滚事务。

问题是我不知道是否更新了Profile表 在我提交交易之前失败了。我试着冲上去 用于捕获异常的配置文件,以便我可以将状态写入Work 表,但随后我的提交失败,由于引起了异常 个人资料更新。

我该如何处理?在典型的ADO交易中,我的第一个电话 将抛出,但我可以捕获并仍然更新其他表 事务。

这是我的代码的样子 - 相当标准。这不是 我的实际代码,所以请关注问题,而不是我不是 处理我的交易或关闭我的会话;):

try
{
    ITransaction trans = _session.BeginTransaction();

    var work = _repo.GetWork();
    var profile = _repo.GetProfile(work.ProfileId);

    try
    {
        profile.UpdateWithNewValues(work);
        _session.SaveOrUpdate(profile);
        _session.Flush();
        work.Status = "Success";

    }catch{
      work.Status = "Failure";
    }

    _session.SaveOrUpdate(work);
    trans.Commit();

}catch{

    trans.Rollback();

}

我意识到Flush()不起作用,但我不知道怎么回事 这样做。

2 个答案:

答案 0 :(得分:0)

我没有看到在刷新之前有trans.Commit的问题。这是一个例子(稍微修改过看起来像你的):

Profile profile;
Work work;
ITransaction tx;

try
{
    session.SaveOrUpdate(profile);  

    work.Status = "Success";    
    session.SaveOrUpdate(work);

    tx.Commit();
}
catch (Exception)   // wroh oh...
{
    try
    {
        work.Status = "Failure";
        session.SaveOrUpdate(work);

        tx.Commit();
    }
    catch (Exception)
    {
        if (!tx.WasRolledBack)
        {
            tx.Rollback();
            session.Clear();
        }

        throw;
    }
}
finally
{
    if (session.IsOpen)
    {
        // Whatever happened, Flush/Persist at the end.
        session.Flush();
    }
}

答案 1 :(得分:0)

需要对您的要求作出一些澄清。

1)>>如果对Profile表的更新成功,并且对Work表的更新失败,我需要回滚事务

我原以为Work就像审计跟踪更新一样,如果Profile更新工作则不应该失败。如果是这种情况,那么您不应该回滚您的交易。但是,话虽如此,您的代码已经符合此要求。

2)>>如果对Profile表的更新失败,我需要更新Work表上的状态。

如果更新失败,那么您将回滚您的交易。您将无法更新工作表,除非您有两个单独的事务(一个用于配置文件和工作(作为当前),然后另一个用于工作)。这对你有意义吗?