Maybe you didn’t know but the System.Transactions.TransactionScope object in .NET doesn’t play nice together with the async/await syntax. As long as all the code inside the TransactionScope
is executed on the same thread, there is no issue. But when you start combining it with async/await you get into trouble. The following code doesn’t work in .NET 4.5:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public async Task WrapInsideATransaction() { | |
using (var tx = new TransactionScope()) | |
{ | |
await SomeAsyncMethod(); | |
tx.Complete(); | |
} | |
} | |
private async Task SomeAsyncMethod() | |
{ | |
await Task.Delay(1000); | |
} |
Whenyou try to execute this code, it will fail with the following error:
System.InvalidOperationException : A TransactionScope must be disposed on the same thread that it was created.
A fix is available in .NET 4.5.1 but requires some code changes. There is a new enumeration TransactionScopeAsyncFlowOption that can be provided in the TransactionScope constructor. Here is the fixed code:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public async Task WrapInsideATransaction() { | |
using (var tx = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) | |
{ | |
await SomeAsyncMethod(); | |
tx.Complete(); | |
} | |
} | |
private async Task SomeAsyncMethod() | |
{ | |
await Task.Delay(1000); | |
} | |