如果在提交时抛出异常,C# TransactionScope 会回滚吗?

根据微软文档:

TransactionScope.Complete 只是将您的状态通知事务管理器的一种方式,事务管理器提交事务的实际工作发生在 using 块中的最后一行代码之后。事务管理器根据是否调用了 TransactionScope.Complete 方法来决定提交或回滚。

那么,如果在提交事务的过程中出现异常(例如 Internet 关闭、数据库连接关闭)会发生什么?它会回滚还是抛出 TransactionScope 异常?

using (TransactionScope transactionScope = new TransactionScope())
{
    WriteToCloudDatabase(input);
    WriteToCloudDatabase(input);    // I know it will rollback if exception thrown in here.
    transactionScope.Complete();
    // Will it rollback if exception thrown in here? (while committing transactions)
}
stack overflow Does C# TransactionScope rollback if an exception is thrown while committing?
原文答案
author avatar

接受的答案

刚找到答案:它会回滚并抛出 TransactionException。

根据 Microsoft 文档,TransactionScope 通过调用 CommittableTransaction.Commit 方法提交事务。
https://docs.microsoft.com/en-us/dotnet/framework/data/transactions/implementing-an-implicit-transaction-using-transaction-scope

让我们看看 CommittableTransaction.Commit 方法做了什么:

调用此方法时,将轮询所有已注册参与事务的对象,并可以独立地表明他们对提交或回滚事务的投票。如果任何参与者投票决定回滚事务,它就会被回滚,并且此方法会抛出 TransactionException 异常。这是事务的正常情况,您的代码应该捕获并处理此类异常。

Microsoft 关于 CommittableTransaction 类的文档: https://docs.microsoft.com/en-us/dotnet/api/system.transactions.committabletransaction.commit?view=net-5.0#System_Transactions_CommittableTransaction_Commit

try
{
    using (TransactionScope transactionScope = new TransactionScope())
    {
        WriteToCloudDatabase(input);
        transactionScope.Complete();
    }
}
catch (TransactionException)
{
    // If something wrong happens while committing the transaction,
    // it will rollback and throw this exception.
}
catch (Exception)
{
    // If something wrong happens before committing the transaction,
    // it will rollback and that exception will be caught in here.
}

答案:

作者头像

处理 TransactionScope 时。如果调用了 Complete 方法,事务管理器将提交事务。如果调用 Complete 方法后任何代码引发异常,因为 Complete 方法已经被调用,当 transactionScope 被释放时,事务管理器将提交事务。

如果事务管理器由于连接丢失而未能提交事务,则所有打开的事务都应由数据库本身回滚。

相关问题