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

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.

Related

Transaction management in microservices

We are rewriting legacy app using microservices. Each microservice has its own DB. There are certain api calls that require to call another microservice and persist data into both DBs. How to implement distributed transaction management effectively in this case?
Since we are not migrated completely to the new micro services environment, we still writeback data to old monolith. For this when an microservice end point is called, we call monolith service from microservice api to writeback same data. How to deal with the same problem in this case as well.
Thanks in advance.
There are different distributer transaction frameworks usually included and maintained as part of heavy application servers like JBoss and WebLogic.
The standard usually used by such services is Jakarta Transactions (JTA; formerly Java Transaction API).
Tomcat and Spring don't support distributed transactions out-of-the-box. You can add this functionality using third party framework like Atomikos (just googled, I've never used it).
But remember, microservice with JTA ist not "micro" anymore :-)
Here is a small overview over available technologies and possible workarounds:
https://www.baeldung.com/transactions-across-microservices
If you can afford to write to the legacy system later (i.e. allow some latency between updating the microservice and the legacy system) you can use the outbox pattern.
Essentially that means that you write to the microservice database in a transactional way both to the tables you usually write and an additional "outbox" table of changes to apply and then have a separate process that reads that table and updates the legacy system.
You can also achieve something similar with a change data capture mechanism on the db used in the microservice(s)
Check out this answer on "Why is 2-phase commit not suitable for a microservices architecture?": https://stackoverflow.com/a/55258458/3794744

Spring Transaction Management usage

Can anybody provide me an example for Spring Transaction management? I have queries like how it basically works? In Java EE , Application server container used to take care of the transaction using EJB's. I wanted to know ,how spring frameworks helps in the same way?
I hope Introduction to Spring Framework transaction management will help.
The Spring Framework’s transaction management support doesn't requires an application server.
Spring Frameworks Claims declarative transactions of spring framework offer more powerful and more productive programming model than EJB CMT.
Compared to transaction management using EJB Spring frameworks enables application developers to use a consistent programming model in any environment. Once we write our code once it can benefit from different transaction management strategies in different environments.
The Spring Framework provides both declarative and programmatic transaction management.
programmatic transaction management - developers work with the Spring Framework transaction abstraction, which can run over any underlying transaction infrastructure.
declarative model - developers typically write little or no code related to transaction management, and hence do not depend on the Spring Framework transaction API, or any other transaction API.
Spring framework provides central interface for transaction
management i.e. 'PlatformTransactionManager'
There are many implementations if it, one which you can quickly
relate to is DataSourceTransactionManager.
Now, this transaction manager does the lower level work of beginning,
rollback and commit of transaction for you.
If you see the source of DataSourceTransactionManager you will see
the same kind of transaction management code that you have seen when
you handle transaction using JDBC api
But importantly, all these things happen declaratively as part of
proxy advise using Spring AOP
Begin Transaction
DataSource ds = /*initialize DS here*/
Connection con = ds.getConnection();
con.setAutoCommit(false);
Commit Transaction
com.commit();

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

Transaction propagation in multiple servlet context with multiple data source

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.

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