c#transactionsescope只需要回滚一些更改

时间:2015-11-23 08:46:30

标签: c# error-handling transactions rollback transactionscope

我正面临以下问题: 在我的项目中,我已经将错误登录到应用程序正在使用的同一个DB中。这意味着,如果发生错误,那么在每个catch中,都会将错误存储到DB中。 但是,当使用交易时,问题就在于此。发生错误时,tran回滚,但它也会回滚记录的错误,如下所示:

这是公共服务,用于保存客户端更改。

public UpdateClient(client)
{
    try
    {
        TransactionScope scope0 = new TransactionScope();

        // some code

        scope0.Complete();
    }
    catch(Exception ex)
    {
        Logger.LogException(ex); //log the exception into DB
    }    
}

这是公共服务,用于多个客户端的更改:

 public void UpdateClients(clients)
    {
        try
        {
            TransactionScope scope1 = new TransactionScope();
            foreach (client c in clients)
                {
                    UpdateClient(c);
                }
             scope1.Complete();
        }
        catch (Exception ex)
        {
            Logger.LogException(ex);           
        }
    }

这里发生的是,如果使用UpdateClients(),并且在UpdateClient()中发生错误,那么它将在UpdateClient()catch块中登录到DB。 scope0是回滚的,并不会影响记录的异常。但是scope1也是回滚的,并且还会回滚UpdateClient()catch块中存储在DB中的异常。

我知道,有一些选项可以将错误存储在不同的数据库中,等等,但遗憾的是,在目前的开发状态下,这是不可接受的。 有什么办法,如何在没有重大变化的情况下解决这个问题?

1 个答案:

答案 0 :(得分:0)

所以我找到了一个可接受的解决方案。代码将在没有事务的内部方法中实现,并将在catch中引发异常。然后用法如下:

internal UpdateClient(client)
{
try
  {
    // some code
  }
  catch(Exception ex)
  {
    Logger.EnlistException(ex); // collect the exception
  }
}

public UpdateClient(client)
{
  try
  {
    TransactionScope scope0 = new TransactionScope();

    //call internal UpdateClient
    /*internal*/ UpdateClient(client);

    scope0.Complete();
  }
  catch(Exception ex)
  {
    Logger.WriteEnlistedExceptions(ex); // collect and write the exception
  }     
}

public void UpdateClients(clients)
{
  try
  {
     TransactionScope scope1 = new TransactionScope();
     foreach (client c in clients)
     {
       /*interanl*/ UpdateClient(c);
     }
     scope1.Complete();
  }
  catch (Exception ex)
  {
      Logger.WriteEnlistedExceptions(ex);           
  }
}

public partial class Logger
{
  private static List<Exception> _exceptionList = new List<Exception>();
  public static void EnlistException(Exception ex)
  {
    _exceptionList.Add(ex);
  }
  public static void WriteEnlistedExceptions()
  {
    foreach(Exception ex in _exceptionList)
      LogException(ex);
    _exceptionList.Clear();
  }
}