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

Does C# TransactionScope rollback if an exception is thrown while committing?

根据微软文档:

TransactionScope.Complete is merely a way of informing the transaction manager of your status, the actual work of committing the transaction by the transaction manager occurs after the last line of code in the using block. The transaction manager decides to commit or rollback based on whether the TransactionScope.Complete method was called.

那么如果在提交事务的过程中出现异常(如网络宕机、数据库连接关闭)怎么办?它会回滚或抛出 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)
}

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

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

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

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

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

When this method is called, all objects that have registered to participate in the transaction are polled and can independently indicate their vote to either commit or roll back the transaction. If any participant votes to roll back the transaction, it is rolled back and this method throws a TransactionException exception. This is a normal occurrence for a transaction and your code should catch and process such exceptions.
Microsoft documentation: 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.
}