Spring JPA transaction in clustered environment - spring

I use Spring-JPA in my application. I use container managed option for EntityManager and use JTA transaction manager.
this Java EE application is deployed in JBoss clustered environment, will the isolation of transactions be taken care of?
In other words, will two different requests on different JBoss nodes and two different request processed on one JBoss node behave differently in isolation perspective?

The transaction isolation behaviour and limitations are dependent on the database provider. Now if your using Oracle RAC , I haven't seen issues but on a MYSQL instance this is an issue.

Related

Is JTA recommended with Hibernate in Springboot

I have to use hibernate along with spring boot. Is it recommended to use JTA transaction manager in this stack?
If JTA is recommended, how to access current session programmatically in controller or service layer ? with example will be more helpful.
As spring documentation says:
Typically, you need an application server’s JTA capability only if your application needs to handle transactions across multiple resources, which is not a requirement for many applications.
And according to spring boot documentation:
Spring Boot supports distributed JTA transactions across multiple XA resources by using either an Atomikos or Bitronix embedded transaction manager. JTA transactions are also supported when deploying to a suitable Java EE Application Server.
When a JTA environment is detected, Spring’s JtaTransactionManager is used to manage transactions. Auto-configured JMS, DataSource, and JPA beans are upgraded to support XA transactions. You can use standard Spring idioms, such as #Transactional, to participate in a distributed transaction.
As for your second question you can have a look at this answer.

Running Hazelcast put() and replace() calls in the calling thread

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.

Transaction management in Spring: Does support come from Spring or container?

I am trying to understand the transaction management in Spring, and I have got some doubts.
I read a bit about transaction management in EJB world, which can be CMT or BMT. For CMT, as per the documentation, it is Application server (e.g. JBOSS) which manages the transaction.
Now, coming to Spring transaction management, and considering using Web container only (Apache Tomcat), how does this work?
Does Spring have its own transaction management with capability of handling local transaction and global transaction (which works with 2 phase commit). Do the actual support need to come by the underlying container (in this case Apache tomcat) or support from framework is sufficient?
I am not clear how all these pieces fit together.
Can anyone help me understand this?
Spring doesn't include any kind of transaction capability of its own, it only provides ways to connect to transaction functionality provided by the container or by standalone libraries.
If you run your application on Tomcat and don't provide any transaction manager libraries like bitronix, then you get only local jdbc transactions provided by the servlet container.
When you read the bullet points at https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/transaction.html notice it says spring is providing abstractions, that means it is providing access through its own apis and using aop to make transactions nonintrusive, but not providing any implementation of transactional functionality. It's facilitating gluing things together, which is the main thing spring does.

Does global tranactions same as XA transactions?

from Spring documentation(http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html):
16.2.1 Global transactions
Global transactions enable you to work with multiple transactional
resources, typically relational databases and message queues. The
application server manages global transactions through the JTA, which
is a cumbersome API to use (partly due to its exception model).
Furthermore, a JTA UserTransaction normally needs to be sourced from
JNDI, meaning that you also need to use JNDI in order to use JTA.
Obviously the use of global transactions would limit any potential
reuse of application code, as JTA is normally only available in an
application server environment.
Previously, the preferred way to use global transactions was via EJB
CMT (Container Managed Transaction): CMT is a form of declarative
transaction management (as distinguished from programmatic transaction
management). EJB CMT removes the need for transaction-related JNDI
lookups, although of course the use of EJB itself necessitates the use
of JNDI. It removes most but not all of the need to write Java code to
control transactions. The significant downside is that CMT is tied to
JTA and an application server environment. Also, it is only available
if one chooses to implement business logic in EJBs, or at least behind
a transactional EJB facade. The negatives of EJB in general are so
great that this is not an attractive proposition, especially in the
face of compelling alternatives for declarative transaction
management.
For me it looks like distributed transaction description(XA).
Am I wrong or Spring really calls XA tranactions as global.

Sharing JMS and Hibernate transactions in a Spring MDB using Oracle Streams AQ?

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.

Resources