Reputation: 10211
Given following code structure
func1()
{
using (TransactionScope1)
using (connection1)
{
"insert into table A"
func2()
"select from table B"
}
}
func2()
{
using (TransactionScope2)
using (connection2)
{
foreach (x in y)
{
"select from table A"
"insert into table B"
}
}
}
If TransactionScope2
was rolled back, then "select from table B"
fails with The operation is not valid for the state of the transaction
. As I understand TransactionScope2
is joining with the first one and rolls them both back.
So I changed it to create it with TransactionScopeOption.RequiresNew
, which in turn results in timeout on "select from table A"
.
The idea is to let second transaction read data from first one, but commit/rollback independently. My guess is IsolationLevel
needs to change somehow, but I don't really understand the options for it.
EDIT:
Perhaps it is easier to understand the problem if we name the func1
and 2. Basically func2
is a DAL functionality, and and func1
is a unit test for it. func1
creates some sample data, gets func2
to perform some actions on it, checks the result then rolls the entire thing back regardless of wherever func2
was successful or not.
EDIT2: after reading up some more I think the following code should work, but for some reason I still get timeouts on select from table A
func1()
{
using (var txn = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted }))
using (connection1)
{
"insert into table A"
func2()
"select from table B"
}
}
func2()
{
using (var txn = new TransactionScope(TransactionScopeOption.RequiresNew))
using (connection2)
{
foreach (x in y)
{
"select from table A"
"insert into table B"
}
}
}
Upvotes: 2
Views: 472
Reputation: 273169
You have a nested TransactionScope.
By default they are linked, without further action (RequiresNew) from you, the outer scope will fail (RollBack) when the inner one does.
This way they will be independent:
func2()
{
using (TransactionScope2 =
new TransactionScope(TransactionScopeOption.RequiresNew))
using (connection2)
{
...
}
}
Upvotes: 2