Problems with TransactionScope and Oracle

we wrote a C # 3.5 client talking to an Oracle database (11g) using ODP.NET.

This application has a batch process in which long work is performed that performs various database calls in TransactionScope.

In our development environment, everything is going well, but in the UAT environment of one of our clients (who has a lot of data), two variables arise (sometimes one, sometimes the other ...):

  • Unable to write to a distributed transaction
  • Operation aborted. (internal exception: Transaction timeout)

We are currently using a timeout of one day for a transaction (for testing purposes).

Starting the specified process in a UAT environment will stop after approx. 10 minutes with one of the above exceptions, so don't get close to the timeout value.

Here is the stacktrace snippet for the second error:

at System.Transactions.TransactionStatePromotedAborted.CreateAbortingClone(InternalTransaction tx)
   at System.Transactions.DependentTransaction..ctor(IsolationLevel isoLevel, InternalTransaction internalTransaction, Boolean blocking)
   at System.Transactions.Transaction.DependentClone(DependentCloneOption cloneOption)
   at System.Transactions.TransactionScope.SetCurrent(Transaction newCurrent)
   at System.Transactions.TransactionScope.PushScope()
   at System.Transactions.TransactionScope..ctor(TransactionScopeOption scopeOption)
   at System.Transactions.TransactionScope..ctor()
   at Application.Domain.DataAccess.Oracle.EntityDaoBase`2.SaveItem(TEntity item, EntityReference`1 user)

The process tries to save the item in the database within the scope of the transaction, but stacktrace indicates that the constructor has fallen into the TransactionScope class, which means that it creates a new TransactionScope.

Am i still right?

Since I know little about the inner workings of TransactionScope, but it seems that when you call a method within the scope, it creates a new transaction (presumably inheriting from the external transaction).

Maybe if I'm right, this new transaction does not inherit the correct timeout (but by default), so the nested transaction will cause this timeout exception?

, - , ? , , .

!

1:

:

public void SomeLengthyBatchProcess()
{
   using (var transaction = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(1, 0, 0, 0)))
   {
       foreach (var item in Items)
       {
          SaveItemToDB(item);
       }

       transaction.Complete();
   }
}

public void SaveItemToDB(object item)
{
   using (var transaction = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(1, 0, 0, 0)))
   {
       // Performing data persistency here

       transaction.Complete();
   }
}

2:

, , SaveItemToDB. , , , TransactionScope, -.

, -, ( -).

, :

  • - ?
  • , - , - (, , ), -, 1 , . 10 ?
  • Oracle , ?
  • , , , ?

, .

(btw: , , DAL , , , , , - , )

, !

+3
6

, TransactionScope .

, TransactionScope Oracle , , SQL Server , .

.

+5

machine.config 10 ... , , , .

+1

, ? , , , System.Transactions. . , "" , , ODP.NET 11.1.0.6.20 .

0

, , , .

RAC? , , /. System.Transactions Oracle , , , RAC .

: ( ). oracle ( ). , RAC, , .net .

. oracle, , DTP.

0

, , ... , IDbConnection ( ). , , . - , .

0

:

  1. , - , - (, , ) - , 1 , . 10 ?

TransactionManager.MaximumTimeout, , . 10 minutes,

MachineSettingsSection .

:

  • - ?

, (.. RequiresNew, Required Required, Suppress ) transaction timeout, , , - .

, (.. Required, Required RequiresNew ), timeout time, , .

- - - , - , Complete() d .

Btw, TransactionManager.MaximumTimeout . . , , - - .

  1. Oracle , ?

"" DB, , DTC. , Oracle ODP.Net, , (this), , ( , ?).

You can or cannot prevent simultaneous connections even with nested areas and for different databases (if they are on the same server).

0
source

Source: https://habr.com/ru/post/1754583/


All Articles