2010-09-14 32 views
0

我有一个我经常碰到的场景。与标准的ADO交易相比,使用 很简单,但与NH(我知道)没有太大关系。在活动事务中执行Flush()

我有2个表来更新。第一个包含配置文件信息 (配置文件),另一个(工作)包含需要进行的记录更改 以及这些更改的状态。对于 配置文件表的每次更新,工作 表中的状态都会更新。

  • 如果更新配置文件表失败,我需要更新工作表上的 状态。
  • 如果更新配置文件表成功,并且更新到 工作表失败,则需要回滚该事务。

问题是,我不知道更新配置文件表 失败,直到我提交事务。我尝试在 配置文件上执行刷新以捕获异常,以便我可以将状态写入工作 表中,但随后由于 配置文件更新导致的异常导致我的Commit失败。

我该如何处理?在典型的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(); 

} 

我认识到,同花顺()是行不通的,但我不知道 如何做到这一点。

回答

0

需要您的要求一些澄清。

1)>>如果更新配置表成功,并更新到工作表失败,我需要回滚事务

我本来以为工作就像是一个审计跟踪更新,并应如果配置文件更新正常,则不会失败如果是这种情况,那么你不应该回滚你的交易。然而,说了这些,你的代码已经符合这个要求。

2)>>如果更新配置文件表失败,我需要更新工作表上的状态。

如果更新失败,那么您将回滚事务。除非您有两个单独的交易(一个用于Profile和Work(作为当前),另一个用于Work),否则将无法更新工作表。你能理解这个吗?

+0

是的,我意识到,但希望得到一个更简单的答案。这实际上是一个批处理过程,所以我省略了相关的细节。感谢您的建议。 – 2010-09-15 13:51:47

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(); 
    } 
} 
+0

感谢您的想法,但这不会因为几个原因。首先,如果第二个交易失败,我将无法回滚第一笔交易。其次,一旦出现异常,该事务会保留它以进行任何进一步的commit()调用。 – 2010-09-14 20:40:14