Is it possible to make operations on EhCache make part of Spring's JpaTransactionManager?
During the transaction I'm doing some operations (put/evict) on EhCache and I want them to be committed when transaction succeeds and rollbacked when transaction fails. Just like the regular behavior on a database transaction.
How can I achieve this using Spring and Hibernate?
Do I need a JTA transaction manager for this?
Related
I'm currently using the #Transactional annotation to save data to a database, and would like to know how to change the transaction so it affects other resources like message queues. I didn't set up beans or anything to make dealing with the database transactional - I just added the #Transactional annotation and nothing else.
You are thinking to enter complicated and slow world called two phase commit transactions. For such case you would need to use distributed transactions manager like Atomikos. JEE has JTA (Java Transaction API) abstractions for it.
I would suggest to avoid this world as much as possible, because of slowness.
Here are few Spring Boot examples I created. They combine distributed transactions with database and JMS queue.
Combining even more than two data sources into distributed transactions would be extremely slow.
Is it possible to force Hazelcast to run put(), replace(), and delete() methods on the TransactionalMap on the calling thread? I want the XA transaction to carry over from writing to Hazelcast to writing to the database in the MapStore, but Hazelcast is queueing the changes to be run on other threads, so they aren't in the same transaction context.
I've got it set up as a write-through persistence, but I see that it's queueing the TxnSetOperation and running them on a separate thread.
This is in a Spring Boot application using the Hazelcast autoconfiguration with a JPA / Hibernate store backing to PostgreSQL.
MapStore operations don't run in the same transactional context. If you want transactional persistent updates with Hazelcast, you need to use XA transactions and not enable MapStore. Then you can set the persistent store as a different XA resource in your context. You can have a check the related section in Hazelcast's reference manual: http://docs.hazelcast.org/docs/latest/manual/html-single/index.html#providing-xa-transactions
Alsparlan's answer is partially correct, but there's no way to enlist a resource in a MapStore with the same transactional context as your actions against the Hazelcast TransactionalMap. The link he provided does NOT talk about this (unfortunately), but the Javadoc for TransactionalMap does:
When using MapStore, the call to any MapStore method is outside the transactional boundary. If you need to have an XATransaction spanning Hazelcast operations and one more other XAResources (such as a database), you should not use MapStore. Instead, enlist both resources in a transaction
I've removed my MapStore usage and wired my Spring Boot repositories directly into my services so I can make my changes to Hazelcast and my datasource in the same service methods inside the same transaction. Along with this solution to declaratively enlisting the Hazelcast XAResource this is working for me now.
How to synchronize JMS and JPA transactions with Spring without JTA?
Ideally, both JPA and JMS should roll back if a failure (exception) happens before successful return from JMS transaction commit.
The case is for receiving of messages by a DefaultMessageListenerContainer. Message handling code stores to JPA repo.
Is it enough to have DMLC to use a JPA transaction manager?
Or should TransactionAwareConnectionFactoryProxy with "synchedLocalTransactionAllowed"="true" be used to
wrap JMS connection factory?
That is how it was done in best-jms-db pattern described here
I run the test from the page above, and they works well. However, I modified them.
They use DMLC with reference to JPA transaction manager, and there is no TransactionAwareConnectionFactoryProxy. That works even better!?!
Both JPA and JMS transactions are rolled back after simulated JMS infra failure.
How can that be possible??
Test code can be found here
In my application I need to store some data to the RDBMS DB and some data to the MongoDB in the same transaction and I am using Spring JTA for my RDBMS transactions.
I am new to MongoDB and i am not sure that will this Spring JTA supported by MongoDB. What's the way or api to handle a transaction programmaticaly in MongoDB as MongoDB doesn't support transaction.
As like working with RDBMS and by annotating a method #Transactional, all operation's in method done as a single atomic operations and if an error occur automatic rollback done by Spring JTA but how we can achieve this using MongoDB?
You can use atomic operations or two-phase commit. Also Check this out. This article explains about plugin developed for Mongo that promises not only transactions but also a boosting in performance.
I'm using Oracle 11g for my database and its Oracle Streams AQ feature as JMS implementation.
For all I know, it should be possible to implement a Spring based message-driven POJO (MDP) that uses the same data source for both transactional data access and JMS transactions -- all without XA-Transactions (IIRC, this was marketed as a feature of SpringSource Advanced Pack for Oracle).
Is this possible using Hibernate as well? Ideally, my MDP would start a JMS transaction and read a message from a queue, then re-use the transaction for data access through Hibernate. If anything goes wrong, the JMS and database transaction would both be rolled back, without using 2-phase commit (2PC).
I'm not much of a transaction guru, so before I start digging deeper, can anyone confirm that this is possible and makes sense as well?
Update:
What I want is an implementation of the Shared Transaction Resource pattern. The sample code demonstrates it for ActiveMQ and JDBC, but I need to use Oracle Streams AQ and Hibernate.
Update2:
The SpringSource Advanced Pack for Oracle has been open sourced as part of Spring Data JDBC and it "provides the option of using a single local transaction manager for both
database and message access without resorting to expensive distributed 2-phase commit
transaction management".
2PC shouldn't be necessary, as you say, since the appserver should take care of it. However, you'll pretty much have to use JTA (i.e. JavaEE container) transactions, rather than vanilla DataSource transactions, since JMS only works with JTA.
This isn't a big deal, it's just a bit more fiddly:
Your Spring config should use
<jee:jndi-lookup/> to get a
reference to your container's
DataSource, and you inject that
data source into your spring-managed
hibernate SessionFactory.
You then need to introduce a transaction manager into the context (<tx:jta-transaction-manager/> should work in most app-servers).
In your Spring JMS MessageListenerContainer, plug the above transaction manager reference into it.
Does that all make sense, or should I elaborate? This setup should ensure that the container-managed transactions are held across JMS and Hibernate interactions.