Transaction propagation in multiple servlet context with multiple data source - spring

We have modularised our application in clustered architecture like multiple servlet context with different datasource using hibernate and packaging in muliple war files. For eg: moldule1->hibernate sessionfactrory ->datasource 1(module1.war), moldule2->hibernate sessionfactrory ->datasource 2(module2.war)....
Spring RMI is used to integrate module1 and module2 services.
Here my question is, how to propagate the transaction between these modules, so that when module 2 fails to insert then module1 should roll back?

You can't without using EJB, per the Spring documentation:
Spring's support for RMI, you can transparently expose your services through the RMI infrastructure. After having this set up, you basically have a configuration similar to remote EJBs, except for the fact that there is no standard support for security context propagation or remote transaction propagation.
...and:
Last but not least, EJB has an advantage over RMI in that it supports standard role-based authentication and authorization and remote transaction propagation.

Related

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.

How to access EJB bean through context lookup from ServletContextListener

Need to call a EJB service from the servlet context listener's contextInitialized() method. Application is running on JBOSS, though the context listener works fine, I'm not able to access the EJB bean through JNDI look up.
Because the web deployment in JBOSS happens before EJB beans are bound with JNDI tree. How to overcome from this? Is there a way to configure JNDI bind early or start the web deployment later once EJB's are completely deployed?
I had put Thread.sleep() before the service call in the contextInitialized() method, it is working fine in my JBoss5.1.0 GA, and the same did not work in other machines JBoss of same version.
Applications needs this because, we want to load some master data from the DB and make it available in the web layer (kind of caching). Does JBOSS startupmbean suit this requirement? If yes how can I make the data available to web layer?
Also if any alternative ways are available, please suggest.
Poll for the EJBs in contextInitialized(). So instead of just sleeping for a certain time, try to connect to the EJB. If that fails, sleep, and retry, until the EJBs are available. In this case the context initialization is blocked.
Implement the cache as a lazy one: Fill the cache during the first query (and use the same polling procedure: connect to the EJB, retry until it becomes available). In this case the cache blocks.
You could split your deployment into two parts: One for the EJBs, one for the web application. Then deploy the first, and delay deployment of the web application until the EJBs are bound (either by watching the log file or by trying bind to the EJB from a command line app)

Distributing business logic across different servers(like JBoss/Glassfish) using Spring and still under one transaction

I am willing to create an example(code) using Spring in which business logic to be distibuted across different servers like JBoss or Glassfish and still under one transaction? First of all is this possible in Spring. I know using EJB has this option. Likewise do we have a similar technique in Spring also? I am looking for Synchronous communication approach and not using asynchronous message oriented middleware. Any help/pointer appreciated.
Thanks
Prakash
Spring has support for RMI or provides its own remoting mechamism HttpInvoker but according to the doc they don't provide any remote transaction propagation.
Similar questions:
Spring Distributed Transaction Involving RMI calls possible?
Transaction propagation in multiple servlet context with multiple data source

Resources