Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中尝试/捕获TransactionScope#_C#_Asp.net_Transactionscope - Fatal编程技术网

C# 在C中尝试/捕获TransactionScope#

C# 在C中尝试/捕获TransactionScope#,c#,asp.net,transactionscope,C#,Asp.net,Transactionscope,我在c代码中使用事务。在TransactionScope中,我记录了几乎所有的内容,以确保在测试中完成所有工作。但若在事务中发生了什么事情,它就会捕捉到我的日志类并没有写任何东西。在localhost中,我将TransactionScopeOption更改为“抑制”,因为数据库不在我的服务器中。当我调试一切正常时,我可以写入日志文件。但当我更改为“必需””时,如果它出现错误,它会像往常一样取消所有操作,但它也无法写入第一个日志。 我怎样才能解决这个问题 我的代码示例: TransactionOp

我在c代码中使用事务。在TransactionScope中,我记录了几乎所有的内容,以确保在测试中完成所有工作。但若在事务中发生了什么事情,它就会捕捉到我的日志类并没有写任何东西。在localhost中,我将TransactionScopeOption更改为“抑制”,因为数据库不在我的服务器中。当我调试一切正常时,我可以写入日志文件。但当我更改为“必需””时,如果它出现错误,它会像往常一样取消所有操作,但它也无法写入第一个日志。 我怎样才能解决这个问题

我的代码示例:

TransactionOptions tr = new TransactionOptions();
tr.IsolationLevel = System.Transactions.IsolationLevel.Serializable;
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, tr, System.Transactions.EnterpriseServicesInteropOption.Automatic))//System.TimeSpan.MaxValue))
{
    bool status = false;
    // this log must be written anyway but it won't when it gives an error.
    LogProcess log = new LogProcess(Ssession["DBNAME"], new Guid(), "Transaction begun.");
    try
    {
        // process 1
        // process 2
        .
        .
        .
        if(status)
        {
            LogProcess log1 = new LogProcess(Ssession["DBNAME"], new Guid(), "Transaction will complete soon.");
            scope.Complete();
            LogProcess log1 = new LogProcess(Ssession["DBNAME"], new Guid(), "Transaction completed.");
        }
        else
        {
            LogProcess log2 = new LogProcess(Ssession["DBNAME"], new Guid(), "Transaction will dispose.");
            scope.Dispose();
            LogProcess log2 = new LogProcess(Ssession["DBNAME"], new Guid(), "Transaction disposed.");
        }

    }
    catch(Exception ex)
    {
        LogProcess log1 = new LogProcess(Ssession["DBNAME"], new Guid(), "Transaction exception. Error: " + ex.Message);
        scope.Dispose();
    }
}

首先,我发现您的代码示例的结构非常混乱。使用TransactionScope时,通常不会在调用scope.Complete()或scope.Dispose()后编写语句。此外,using语句为您处理作用域,因此如果您可以帮助的话,不应该显式调用scope.Dispose()。换句话说:尝试重构代码,使其看起来像这样:

private void PerformTransactionalOperation()
{
    Log.Write("Starting operation.");        

    try
    {
        using (var scope = CreateTransactionScope())
        {
            if (PerformTransactionalOperationCore())
            {
                Log.Write("Committing...");
                scope.Complete();
                Log.Write("Committed");
            }
            else
            {
                Log.Write("Operation aborted.");
            }
        }
    }
    catch (Exception exception)
    {
        Log.Write("Operation failed: " + exception.Message);
        throw;
    }
}

private bool PerformTransactionalOperationCore()
{
    // Perform operations and return status...
}
其次,事务作用域专门设计为仅在未引发异常时完成,因此可以通过让PerformTransactionalOperationCore引发特定异常而不是返回false来改进您的设计


然后讨论日志问题:确保您的日志框架不参与与您正在记录的操作相同的事务。您可以通过始终使用选项Suppress在TransactionScope中进行日志记录来实现这一点(即,当您首先登录到事务感知的资源(如数据库)时)。顺便问一下,为什么要通过实例化新的LogProcess实例来编写日志语句

首先,我发现您的代码示例的结构非常混乱。使用TransactionScope时,通常不会在调用scope.Complete()或scope.Dispose()后编写语句。此外,using语句为您处理作用域,因此如果您可以帮助的话,不应该显式调用scope.Dispose()。换句话说:尝试重构代码,使其看起来像这样:

private void PerformTransactionalOperation()
{
    Log.Write("Starting operation.");        

    try
    {
        using (var scope = CreateTransactionScope())
        {
            if (PerformTransactionalOperationCore())
            {
                Log.Write("Committing...");
                scope.Complete();
                Log.Write("Committed");
            }
            else
            {
                Log.Write("Operation aborted.");
            }
        }
    }
    catch (Exception exception)
    {
        Log.Write("Operation failed: " + exception.Message);
        throw;
    }
}

private bool PerformTransactionalOperationCore()
{
    // Perform operations and return status...
}
其次,事务作用域专门设计为仅在未引发异常时完成,因此可以通过让PerformTransactionalOperationCore引发特定异常而不是返回false来改进您的设计


然后讨论日志问题:确保您的日志框架不参与与您正在记录的操作相同的事务。您可以通过始终使用选项Suppress在TransactionScope中进行日志记录来实现这一点(即,当您首先登录到事务感知的资源(如数据库)时)。顺便问一下,为什么要通过实例化新的LogProcess实例来编写日志语句

日志是否也写入数据库?如果是,那就是你的问题。出现错误时,日志也将回滚。您需要将日志包装到另一个事务中,或者像文本文件一样记录到其他地方。@tucaz谢谢,您说得对。但是,即使在scope.Complete()之后一切正常,它也无法写入日志。这听起来像是日志记录的问题。什么是“逻辑过程”?我对它不熟悉。它在您的应用程序中的其他地方工作吗?出于性能原因,大多数日志提供程序都会“批量”将日志写入DB,如果您等到发出一定数量的日志请求,那么您将看到它们一起出现。此外,我还担心using语句中的手动作用域.Dispose()。您不需要它,因为它一离开“使用”范围就会被处理。日志是否也写入数据库?如果是,那就是你的问题。出现错误时,日志也将回滚。您需要将日志包装到另一个事务中,或者像文本文件一样记录到其他地方。@tucaz谢谢,您说得对。但是,即使在scope.Complete()之后一切正常,它也无法写入日志。这听起来像是日志记录的问题。什么是“逻辑过程”?我对它不熟悉。它在您的应用程序中的其他地方工作吗?出于性能原因,大多数日志提供程序都会“批量”将日志写入DB,如果您等到发出一定数量的日志请求,那么您将看到它们一起出现。此外,我还担心using语句中的手动作用域.Dispose()。你不需要它,因为它一离开“使用”范围就会被处理掉。我要试试。非常感谢。我的日志类通常非常广泛。我的客户几乎什么都想看。这只是测试的一个例子。我理解如果客户要求,您需要放入大量日志语句,我只是好奇您为什么选择这样实现它:每次需要记录一些东西时实例化一个新对象不是很传统(假设LogProcess构造函数执行实际写入)。我要试试。谢谢。我的日志类通常很宽。我的客户希望看到几乎所有的东西。那只是一个测试的例子。我理解你的要求,如果你的客户要求,你需要放很多日志语句。我只是好奇你为什么选择这样的方式来实现它:instanti不是很传统每次需要记录某些内容时,都会使用一个新对象(假设LogProcess构造函数执行实际写入)。