Open Mobe91 opened 5 years ago
Well, it is the application's responsibility to terminate active transactions. Why is this a problem?
What's the use of a timeout then? I want transactions to be actively rolled back, otherwise they continue to block database connections.
Narayana does the same (http://narayana.io/docs/project/index.html):
When a top-level transaction is created with a non-zero timeout, it is subject to being rolled back if it has not completed within the specified number of seconds. Narayana uses a separate reaper thread which monitors all locally created transactions, and forces them to roll back if their timeouts elapse. If the transaction cannot be rolled back at that point, the reaper will force it into a rollback-only state so that it will eventually be rolled back.
Even if such behavior is not desired for whatever reason, the transaction must still be removed when the underlying connection is repead. Apparently, this is not happening at the moment.
Reaping and transaction timeout are different things - I don't see why reap should remove a transaction: the application will typically get an exception and rollback on its own.
We used to rollback on timeout by default, but some XAResources don't like the rollback happening in a different thread than the application thread. We then changed it to the current behaviour to have less useless warnings because of that.
Maybe the real question is: why are your connections being reaped, and why are there pending transactions? Are you able to shed some light on that?
Thanks
the application will typically get an exception and rollback on its own.
Why should the application receive an exception if everything is going well but the operations involved in the transaction just take too long?
Maybe the real question is: why are your connections being reaped, and why are there pending transactions? Are you able to shed some light on that?
The transactions are being reaped because I configured a reap timeout on the datasource level. At the time of reaping, there are pending transactions because the transactions simply run longer than the configured reap timeout - this can happen for whatever reason like high database load, IOPS limitations etc. IMHO it is legitimate for a connection to have an active transaction associated at the time it is being reaped.
It looks like you are abusing reap for timeouts. Reaping is there to detect application conditions where connections are never released to the pool.
In your case, what you want is probably the queryTimeout at the level of the JDBC statements.
How are you demarcating transactions in your application? You should still configure rollback on exceptions.
It looks like you are abusing reap for timeouts. Reaping is there to detect application conditions where connections are never released to the pool.
In your case, what you want is probably the queryTimeout at the level of the JDBC statements.
I am aware that this is not the intended purpose of the Atomikos reaper but currently, this is the only way to force a transaction to stop afaik. A transaction timeout cannot be substituted with a statement timeout. There may be long running transactions consisting of short lived statements that do not time out. Anyway, the reaper must account for connections that have transactions in progress and correctly clean up these transactions.
How are you demarcating transactions in your application? You should still configure rollback on exceptions.
I am using Spring's @Transactional
annotation which will cause a transaction rollback when an exception is thrown. But that's actually not the point because the code executed in the transaction is fine, i.e. no exception is thrown. I just want to account for possibly malfunctioning transactions that run too long for some reason and I want such transactions to be rolled back after a specified timeout.
OK well reap will close / destroy connections that are in use for too long. This should give an exception on which you can rollback. I don't see what else makes sense, since rollback should be done by the application thread.
16:53:31.998][WARN ][Atomikos:4][c.a.logging.Slf4jLogger.logWarning(Slf4jLogger.java:24)]Transaction MyApp.tm160752920191300011 has timed out and will rollback.
I'm waiting so long time for saving to database and nothing happens. Does it mean that during some time without response, I have to throw an exception for rollback transaction?
In my case were bad demarcations of transactions. It came to blocking of tables in sql server and crushing of Jms broker. (see queues in sql server)
Thanks for GuyPardon about comment on 25 Apr 2019. and Mobe91 what raised this subject here.
When using single threaded 2PC, a transaction timeout will only produce a log message like
Atomikos merely does a
setRollbackOnly()
on the transaction but does not actually force it to rollback immediately. It is then left to the connection reaper to terminate the connection occupied by the transaction. Also, the transaction reaper fails to remove any active transactions for the reaped connection, i.e.com.atomikos.icatch.imp.TransactionServiceImp#removeTransaction
is not invoked. This causes thecom.atomikos.icatch.imp.TransactionServiceImp#tidToTransactionMap_
to pile up transaction mappings which eventually prevents new transactions from being started because the size ofcom.atomikos.icatch.imp.TransactionServiceImp#tidToTransactionMap_
eventually exceedscom.atomikos.icatch.imp.TransactionServiceImp#maxNumberOfActiveTransactions_
.This kind of makes the transaction manager unusable as a whole... Feedback is appreciated.