2010-08-13 75 views
2

我有一个使用存储过程与数据库通信的n层C#ASP .Net应用程序服务器。在SQL中隔离提交事务

我有一个服务层,如果使用TransactionScope.requiresNew引发异常,它将回滚所有ADO .net事务。

在我的存储过程中,我想跟踪登录尝试号码,所以我们希望保持事务框架原样,但希望拥有我们提交的独立事务。

我该怎么做?

我试过在我们的数据层中使用一个新的TransactionScope.RequiresNew,但是这没有效果。

回答

0

奇怪 - RequiresNew内部(日志记录)TransactionScope应该可以工作。

在下面的嵌套事务中,TransactionScopeOption.Suppress或TransactionScopeOption.RequiresNew都适用于我 - 内部事务已提交(Dal2.x),而外部事务已中止(Dal1.x)。

try 
    { 
     using (TransactionScope tsOuter = new TransactionScope(TransactionScopeOption.Required)) 
     { 
      DAL1.Txn1(); 
      using (TransactionScope tsLogging = new TransactionScope(TransactionScopeOption.Suppress)) 
      { 
       DAL2.Txn2(); 
       tsLogging.Complete(); 
      } 
      throw new Exception("Big Hairy Exception"); 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 

编辑:混合的TransactionScope和明确的T-SQL事务是要避免的 - 这是在你即http://msdn.microsoft.com/en-us/library/ms973865.aspx引用相同的链接说明,下面引用

TransactionScopes管理事务升级很聪明 - 他们将使用(例如,只有在事务跨越多个数据库或资源时才使用DTC,例如SQL和MSMQ)。他们还使用SQL 2005+轻量级事务处理,因此到同一数据库的多个连接也将在事务中进行管理,而无需DTC的开销。

恕我直言,关于是否使用Suppress vs RequiresNew的决定将取决于您是否需要在事务中执行您的审计 - RequiresNew为孤立的txn,Suppress为none。

当使用System.Transactions的, 应用程序不应该直接 利用事务编程 接口上的资源管理器,用于 例如,T-SQL BEGIN TRANSACTION或 COMMIT TRANSACTION动词,或在 MessageQueueTransaction()对象 System.Messaging命名空间,当处理MSMQ的 。这些机制 会绕过 System.Transactions的处理的分布式 事务管理,并结合 使用System.Transactions的与这些 资源管理器“内部” 交易将导致不一致的结果 ....不要混合使用两种

+0

嗨@nonnb,谢谢你。我压制应该做什么? – Russell 2010-08-14 01:59:30

+0

经过一番阅读(http://msdn.microsoft.com/zh-cn/library/ms973865.aspx)后,Suppress根本没有任何事务。它也不使用我想要的环境事务。不确定我是否更喜欢交易。我有一个在我的存储过程(BEGIN TRANSACTION,COMMIT)... – Russell 2010-08-14 03:15:41

+0

嗨罗素 - 我编辑了我原来的文章,因为我的评论太大了。如果你可以的话。由于听起来您有策略来控制.NET代码中的交易(例如服务或业务层),因此建议您从sprocs中删除BEGIN TRAN/COMMIT TRAN - TransactionScope取代此。 – StuartLC 2010-08-15 15:59:05