I have a WCF service which includes an operation marked with OperationBehavior(TransactionScopeRequired=true)
and TransactionFlow(TransactionFlowOption.Allowed)
.
The client of this service is also part of the transaction (it has a database as well. This is a simplified example), so this involves distributed transactions and 2-phase-commit.
In order for my database operations to support 2-phase-commit, I've implemented the IEnlistmentNotification interface.
In the prepare phase I write the data to the DB with a transaction tag on it, and in the commit phase I remove the transaction tag from the data. Note that the commit phase includes database access, so it may be a bit slow.
The problem is that from what it seems and from what I've read, the Commit phase is run asynchronously, so for example, the following sequential scenario may not work:
1) Transaction 1: Client inserts A
2) Transaction 2: Client inserts B which relies on A (server looks up A, extracts information from it and uses it to insert B)
Since the commit phase of transaction 1 may not have yet finished on the server side, transaction 2 may not find A (since it's still marked with 'transaction 1' tag).
These 2 transactions may quickly occur one after the other, so it's a matter of race condition.
The way I noticed it is when I enabled logging of my DB driver, then the commit became a bit slower and an error occurred on the 2nd transaction. If I disabled the logging then it succeeded. But even if I disable the logging, it's still a matter of race condition, and I wouldn't rely on it in a production environment.
What would be the best way to tackle this issue?