Problems with TransactionScope and Oracle

后端 未结 6 1936
谎友^
谎友^ 2021-01-19 05:35

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

This application has a batch process where a long running task is performed ma

相关标签:
6条回答
  • 2021-01-19 06:17

    the default transaction timeout in machine.config is 10 minutes...that is probably why you are timing out.

    0 讨论(0)
  • 2021-01-19 06:21

    Because we couldn't find a solution, we have decided to stop using the TransactionScope for our purposes and arrange the rollback ourselves.

    I find that TransactionScope and Oracle do not mix well, perhaps SQL Server handles it better, but that is not an option for us.

    Thanks for reading.

    0 讨论(0)
  • 2021-01-19 06:27

    although an old question, am hoping this answer helps... this especially happens for a long running transactions because the underlying IDbConnection does not remain open for longer duration and new connection is created for parts of transactionscope (connection pooling). it is for the same reason, the long transaction could succeed if the same open connection is returned and used else it fails. Only solution for this is to control connection creation and ensure that only one connection is used throughout.

    0 讨论(0)
  • 2021-01-19 06:29

    Is it possible for you to please show a snippet of code? From what you mentioned The only thing I could find was related with System.Transactions. The discussion is here. Of course their "solution" is to make sure you are using at least ODP.NET 11.1.0.6.20 or higher.

    0 讨论(0)
  • 2021-01-19 06:35

    I know this is an old question but I'll add to it since I've seen this quite a bit.

    Are you using RAC? Have you worked with a DBA to see if you're experiencing locking/blocking. I've used System.Transactions with Oracle for years and the only time I've had similar issues is when we were using RAC and additional configuration needed to be done.

    Here's what happens: You start a transaction and are opening connections during the transaction (which is fine). However, the oracle service is not configured for distributed transaction processing (it's a simple checkbox option on the service). So additional connections start spanning more than one instance in the RAC cluster, and the related transactions are unaware of each other causing the .net process to block itself.

    It's a simple fix. The oracle service you are using just needs DTP enabled.

    0 讨论(0)
  • 2021-01-19 06:40

    Addressing the main issue first:

    1. How is it possible that a timeout exception can occur when the timeout setting is (presumably, aside from inner workings that I do not know about) the same for all transaction scopes and has a timeout value defined of 1 day, where the exception occurs after approx. 10 minutes?

    There is the TransactionManager.MaximumTimeout property which is the upper bound of whatever you are trying to set via your scope. On your system, it is set to 10 minutes, but according to the documentation

    This value can be set in the MachineSettingsSection of the config file.

    As to the other questions:

    1. Is it necessary to define timeout values for nested transactions or do they inherit this from the ambient transaction?

    The scope initiating a transaction (i.e. any RequiresNew scope, any outermost Required scope, and any Required scope that has a Suppress scope one level up the nesting stack) will establish a transaction timeout, and as far as my reading of the sources goes, this timeout is not affected by nested scopes.

    However, every nested scope participating in an existing transaction (i.e. any Required scope that has a Required or RequiresNew scope one level up the stack) will establish its own scope timeout that runs in addition to the transaction timeout mentioned above.

    Transaction timeouts and scope timeouts are implemented differently internally, but if any one of these timeouts hits, a transaction yet to be Complete()d would be rolled back.

    Btw, aforementioned TransactionManager.MaximumTimeout only applies to transaction timeouts. Scope timeouts do not have an upper bound. Not that it really matters, as the shortest timeout is what counts anyway.

    1. Is it possible to prevent Oracle from creating a distributed transaction for transactions where the connectionstring is the same?

    As long as you have only one "physical" DB connection open at any single point in time, the scope will not escalate to DTC. If I recall correctly, this works with Oracle ODP.Net, despite (this) seemingly claiming the opposite (maybe it did not work with the version at the time?).

    You may or may not be able to prevent concurrent connections even with nested scopes, and for different databases (as long as they are on the same server).

    0 讨论(0)
提交回复
热议问题