Spring Chained Transaction Manager versus Atomikos - java

Hi I have a distributed transactions and I have to manage them somehow
Also in spring ecosystem ChainedTransactionManager can do that on the other hand in spring document Atomikos can be used for distributed transactions
https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/boot-features-jta.html
Which one I should use?I prefer to stay in spring librarys but Atomikos is much more than spring transaction manager?If someone use them both,Can compare pros and cons

Using Atomikos is a better overall solution. The ChainedTransactionManager is something you can use in some cases. The assumption it makes are stated in the javadocs:
PlatformTransactionManager implementation that orchestrates transaction creation, commits and rollbacks to a list of delegates. Using this implementation assumes that errors causing a transaction rollback will usually happen before the transaction completion or during the commit of the most inner PlatformTransactionManager.
The configured instances will start transactions in the order given and commit/rollback in reverse order, which means the PlatformTransactionManager most likely to break the transaction should be the last in the list configured. A PlatformTransactionManager throwing an exception during commit will automatically cause the remaining transaction managers to roll back instead of committing.
The chance of committing one transaction and the other one failing still remains with ChainedTransactionManager.
Using Atomikos is a real distributed transaction all or nothing on both databases. But this also has some consequences that can affect the support of the application, for example when the TX is fully commited on one DB and prepared on the other, and at that point the application crashes. You'll need to ensure that your application can recover from this scenario. Usually the TX would be fully commited on the second DB when the app is restarted, but that might not happen.
So which one is the right one? It depends.

Related

Can we write custom Spring transaction manager?

Suppose that we have a businessLogic() method that does 2 things: write some information in a local cache and save the same information in the DB using JDBC so that the contents of the cache and the DB are always the same.
I know we can use Spring's JDBC Datasource Transaction Manager to automatically rollback the DB in case of exception. However, how can we define a custom transaction manager that also rollbacks the content of the cache in this case, so that the contents of the cache and the DB are always in sync?
Thanks all.
Gab's answer is right, except for the parts that aren't.
XA is indeed the standard way to coordinate update of multiple resources... except that where the cache is local i.e. in-process, it's not necessarily a resource.
A cache doesn't exactly 'implement JTA', it acts in one of two roles in the XA protocol, according to how it's deployed. It can be an XAResource, but that's usually only required where its lifecycle is distinct from that of the client process. For in-process use, it's more likely to be a Synchronization.
The key difference between these roles is: XAResource is fault-tolerant, but Synchronization is not. For a volatile cache that's in-memory with the client process, it's sufficient to rebuild the cache after a crash by querying the db. For a cache that's out of process, a client crash after the db tx commit but before the cache update would leave the cache out of sync, at least until it expired or was manually refreshed.
Depending on the cache implementation, there is no guarantee it will pick the right mode automatically. See the configuration reference for your chosen implementation e.g. https://infinispan.org/docs/stable/user_guide/user_guide.html#tx_sync_enlist
Spring isn't actually a JTA XA transaction manager either, though it does provide an abstraction layer over them. It's possible to use Spring to drive a database in non-XA mode, but then you have no standard hook for the cache Synchronizations and you need a proprietary interface instead. Or you can have the database do pseudo-XA via a one-phase resource adapter. Full-on 2PC is probably overkill for your use case.
First of all I believe that the task of transaction management for cache is redundant. I advice you to only update the cache if database level transaction is successfully committed.
Most scenarios with cache using are completely acceptable if you have small window between updates of entity in database and its cached state.
If your case rejects any possibility of outdated cache then you probably have to avoid using cache or use something special for caching, probably the same database as your original data supporting transactions. Otherwise you will have problems trying to maintain consistency between two different systems: db level and cache level. Most of the time the best you can achieve is eventual consistency - it means that anyway you will have windows of inconsistent state and only then (eventually) the data will become consistent.
Standard way to deal with transaction distributed among multiple resources is to use XA
You must then access your database using an xa-datasource and use a cache implementation implementing JTA, eg. ehcache.
I'am not very familiar with spring boot, but the transaction manager should manage the transaction synchronization across both resources out of the box with the appropriate configuration (no need to override anything)

Isolation in distributed (global) transactions using JTA

As we know Isolation and Atomicity are two different properties. Atomicity is the "all or nothing" property, either a transaction completes successfully or fails altogether. Atomicity is definetly supported by JTA and the X/Open XA Two Phase Commit Standard on which JTA is based upon.
My question is: Does JTA support isolation? I'm referring only to the case when we use EJBs and JDBC, no frameworks (e.g. Spring) or transaction managers other than JTA.
In other words, let's take the case that we have multiple threads, and let's say that one of them executes the global transaction which performs access and modifications on multiple databases. The other threads perform modifications on the databases but each thread performs modification on only one database and it does it within a transaction.
Are we going to have any concurrency issues like dirty/repeatable/phantom reads inside the global transaction?
AFAIK there is no way to specify the isolation level in JTA.
Isolation is the black sheep of the ACID family. It's not, strictly speaking, a property of the transaction manager. It's entirely controlled by the resource manager i.e. the database. All transactions against the database run at some isolation level. The difference in XA (JTA) transactions is in how that level is selected.
For the most part it isn't possible to achieve the per-transaction isolation level selection control you have with regular transactions, though some resource managers may allow SQL set transaction isolation commands as the first statement in an XA controlled transaction branch. The other model sometimes used is custom flags to XAResource.start, an approach taken by e.g. oracle. For database engines supporting neither of these, the XA transaction defaults to the isolation level configured globally for the database server.
Note that even for 'serializable' transactions, JTA or otherwise, you are still going to have headaches. Read Peter Bailis's excellent ACIDRain paper and then go find a corner to weep quietly in.
http://www.bailis.org/papers/acidrain-sigmod2017.pdf

Exception if no transactions are configured?

I am using spring/hibernate stand alone application. if i dont configure Transactions i am getting below excpetion.
Exception in thread "Thread-1" org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
in spring/hibernate integrated application is it mandatory to have transaction configuration?
Thanks!
Basically, yes. The Hibernate documentation says:
Database, or system, transaction boundaries are always necessary. No
communication with the database can occur outside of a database
transaction (this seems to confuse many developers who are used to the
auto-commit mode). Always use clear transaction boundaries, even for
read-only operations. Depending on your isolation level and database
capabilities this might not be required, but there is no downside if
you always demarcate transactions explicitly. Certainly, a single
database transaction is going to perform better than many small
transactions, even for reading data.

Best way to handle Hibernate Sessions in a layered Spring MVC Web application

If we have a web application which has
heavy UI (Spring MVC + JQuery with JSON)
Hibernate with JPA annotations being the domain model
extend Spring-provided DAO to code DAO layer
JBOSS being the app server with Oracle as backend
Datasource (JNDI) based connection pooling (Not an XA rather Local data source)
also has access to multiple data sources (dealing with multiple DB)
Behaviorally, lot of Data retrieval (70%) and update of data being 30%
What would be the best practices for the following to effectively consume DB connections and also see to that there is no much leakage at connection usage?
would it be better to opt for Hibernate template based DAOs?
What kind of transaction manager would be suggest-able and should we go for AOP-based transaction managementWhere
where to instantiate session and and where to close the sessions to effectively consume connections from connection pooling.
It is true that we need to handle transactions from Service layer but what happens to sessions would they be waiting for longer time (we are not using any opensessioninviewFilter)
which layer is better to handle the checked exceptions (business exceptions) and runtime exceptions.
Sorry for this being bit lengthier question, however I see that this is being a common query and I tried consolidating it. Appreciate your patience and guidance. Thanks for your help.
This sounds like a pretty typical Spring/Hibernate application, so I would recommend following current best practices, which I recently outlined in another answer. Specifically:
Do not extend Spring DAO support classes or use HibernateTemplate. Use the #Repository annotation combined with component scanning, and directly inject the SessionFactory into your DAO.
Use Spring's HibernateTransactionManager, and definitely use declarative transaction management via #Transactional as your default approach.
Let Spring manage that. It will open sessions just in time for transactions by default, but prefer the open session in view pattern enabled by Spring's OpenSessionInViewFilter.
See #3.
Always handle exceptions where they should be handled--in other words, this is a design decision. Note, however, that the Spring transaction framework by default rolls back on unchecked exceptions, but not checked, to match the behavior of the EJB spec. Make sure to set the proper rollback rules (see previous link) anywhere you use checked exceptions.
Additionally, use a connection pool, obviously. Apache Commons DBCP is a great choice. "Not much leakage in connection usage" isn't enough. You have to have zero connection leakage. Depending on Spring to manage your resources will help ensure this. As for any other performance issues, don't try to optimize prematurely. Wait until you see where your problem areas are, and then figure out the best way to solve each one individually. Since your bottlenecks will most likely be database-related, check out the performance chapter of the Hibernate reference to get an idea what you're up against. It covers the important concepts of caching and fetching strategies.
Use JPA EntityManager directly in your DAOs. Be sure not to mark it as Extended
Prefer <tx:annotation-driven /> and #Transactional - only on the service layer
The transaction manager also opens and closes sessions (if one doesn't exist already in the thread). Here it is good to know that sessions are session-per-request. Each request(=thread) has a separate session instance. But a database connection is created only if one is needed, so even if there is a transaction manager around all methods, needless connections won't be opened.
read-only transactions - use #Transactional(readOnly=true) in cases when there is only data retrieval
caching - utilize hibernate 2nd level cache to put entities in memory (instead of fetching them from the database each time)
avoid OpenSessionInView and lazy collections. This is subjective, but in my opinion all objects that leave the service layer must be initialized. For small collections (for ex. list of roles) you can have eager collections. For bigger collections use HQL queries.

How can I see from which TransactionManager given transaction is created in Spring 3.0

In my spring configuration I have two transaction managers defined for two different databases. Is there a way in spring to check on runtime whether given method is running inside transaction and secondly (and more importantly) from which transaction manager was this transaction created.
You can use the TransactionSynchronizationManager. It has a number of methods to tell you whether the transaction is active and what's its name. You can get the resource map (getResourceMap()) and verify what's inside.
Everything in that class is ThreadLocal, so it will give you information about the current transaction.
However, the documentation says:
To be used by resource management code but not by typical application code.
It is not clear why you would need that information. Spring uses declarative transactions so that the actual code does not have to know about (and handle) transactional behaviour. If you need to differentiate between transaction managers in the code, then something might be wrong.

Categories

Resources