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.
Related
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.
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.
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();
I have spring 4 application. At the moment I use JpatransactionManager.
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
Could you tell me how to choose transaction managers?
For instance, when should I use jta transaction manager and when jpa, and what benefit and disadvantages does they have?
And Is I know I have 2 way to work in Spring. First is JPA way and the second Hibernate way. first one includes java standard annotations and standard api and the second is hibenrate implementation. If i need to use JTA, I must use hibernate and not JPA, does not it?
If you want to delegate managed transactions to your Application Server and handle complex transactions across multiple resources you need to use the JtaTransactionManager, but I believe it is not needed in most cases.
Read this for more information http://docs.spring.io/spring-framework/docs/4.0.x/spring-framework-reference/html/transaction.html
Do you need an application server for transaction management?
The Spring Framework’s transaction management support changes
traditional rules as to when an enterprise Java application requires
an application server.
In particular, you do not need an application server simply for
declarative transactions through EJBs. In fact, even if your
application server has powerful JTA capabilities, you may decide that
the Spring Framework’s declarative transactions offer more power and a
more productive programming model than EJB CMT.
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. Many high-end
applications use a single, highly scalable database (such as Oracle
RAC) instead. Standalone transaction managers such as Atomikos
Transactions and JOTM are other options. Of course, you may need other
application server capabilities such as Java Message Service (JMS) and
Java EE Connector Architecture (JCA).
The Spring Framework gives you the choice of when to scale your
application to a fully loaded application server. Gone are the days
when the only alternative to using EJB CMT or JTA was to write code
with local transactions such as those on JDBC connections, and face a
hefty rework if you need that code to run within global,
container-managed transactions. With the Spring Framework, only some
of the bean definitions in your configuration file, rather than your
code, need to change.
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.