Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TransactionStatus.flush() should trigger TransactionSynchronization.flush() when using DataSourceTransactionManager [SPR-14847] #19413

Closed
spring-projects-issues opened this issue Oct 26, 2016 · 1 comment
Assignees
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Oct 26, 2016

Karsten Sperling opened SPR-14847 and commented

TransactionStatus.flush() does not trigger TransactionSynchronization.flush() when using DataSourceTransactionManager, even though this transaction manager supports transaction synchronization, while the same call with JtaTransactionManager and WebSphereUowTransactionManager does.

Given that TransactionSynchronization support is implemented in AbstractPlatformTransactionmanager I would expect this behaviour to be consistent between the various TMs that derive from this.

DefaultTransactionStatus.flush() delegates to SmartTransactionObject.flush() (if the underlying transaction object implements that interface), but then some of the STO implementations call TransactionSynchronizationUtils.triggerFlush() and some don't. Maybe a more appropriate approach would be to have DefaultTransactionStatus itself call triggerFlush() directly after calling STO.flush() and removing the call from the STO sub-classes.

Another wrinkle is that the transaction manager may have been configured to not enable transaction synchronization, in which TransactionSynchronizationUtils.triggerFlush() will raise an IllegalStateException, so DefaultTransactionStatus should probably check for isSynchronizationActive first.

(As motivation for all this, I'm using Ebean ORM with Spring's transaction management, and would like it to be able to correctly participate via it's TransactionSynchronization listener when flush() is called. My workaround is currently to register another TransactionSynchronization before calling TransactionStatus.flush(), and then checking if the flush() call has been propagated, and calling triggerFlush myself otherwise, however this seems pretty hacky.)


Affects: 4.3.3

Referenced from: commits 01e9307, 2874066

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 27, 2016

Juergen Hoeller commented

Generally speaking, flush() is designed as a hint, along the lines of the readOnly attribute on transaction boundaries. Depending on the transaction manager, it may be a no-op (like for JmsTransactionManager and transaction managers with non-smart transaction objects) or just applied to the primary resource (like for HibernateTransactionManager and JpaTransactionManager). It is also up to the particular transaction manager whether and when to trigger a flush on synchronizations: JtaTransactionManager does that on explicit flush() calls, since it does not operate on a primary resource, assuming that it is usually dealing with synchronized ORM resources which also flush in the beforeCommit phase.

You got a point there that DataSourceTransactionManager can be used with synchronized ORM resources as well, even Hibernate etc, with such resources accessing the managed JDBC Connection... as a direct alternative to JtaTransactionManager even according to its documentation. Since DataSourceTransactionManager does not have a flush concept on its primary resource (that managed JDBC Connection}}, it should do the same as JtaTransactionManager and trigger a flush signal on associated synchronizations. We're doing that as of 4.3.4 now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.