Can someone give me a good explanation on the motivation and application of JTA in modern Java applications? I don't want overly technical details. But just a paragraph on why do we need JTA, what does JTA accomplish, and maybe a piece of pseudo code showing how JTA is being used?
Normally, an application performs transactional operations over information resources like Database, JMS etc. As these transactions are totally isolated from each other, it can happen that the application is able to commit one transaction on one resource, but on the other one it fails. It would lead to information inconsistency among these resources, as one got committed and the other not.
XA is an open standard to such a problem. And, JTA is the name given to XA in the J2EE world.
Hope that helps.
Nitin
Greatest book about JTA. Java Transaction Design Strategies By Mark Richards
You can find here a lot of basics about JTA, transactions, XA, Spring, EJB support. Good explanation about all aspects of programming and designing transactional application. Recommend.
JTA defines the semantics (specification + API) of the orchestration that allows for 3rd party enterprise information systems and your application to exchange information with integrity.
JTA Specification. Introduction pretty much sums it up.
JTA allows you to write code or systems having multiple transactional resources: databases, message queues, your own custom resource, or resources accessed from multiple processes, perhaps on multiple hosts, as participants in a single transaction.
This has a fairly nice explanation of what JTA is:
http://www.roseindia.net/interviewquestions/j2ee-interview-questions-2.shtml
To learn more you can look at the link at the top of this page, the pdf version of the tutorial. As you search for JTA you will find code for JTA.
http://docs.sun.com/app/docs/doc/819-3669/bnciz?a=view
JTA allows us to write code which having multiple transaction with resources, databases and resources accessed from multiple processes as participants in a single transaction.
Related
Apologies if this is too vague but I couldn't find a better site to ask this question:
As part of our Database Migration (from Oracle to a NoSql solution), we are using a Persistence layer which can talk to both the solutions. We need to talk to both the layers and exact transaction manager might be decided on the basis of a migration strategy which manages if a given customer is migrated or not.
To achieve this, we were planning to pass an additional parameter (i.e. annotation with the value being the customer id) to all the methods to decide the correct persistence layer to use which internally chooses the right transaction manager.
This seems very counter-intuitive and makes the code look dirty. Is there any better alternative to achieve the same goal?
Thanks!
we have microservice architecture where for most part each microservice is independent. But for some legacy reasons, there is a situation where we have to call another microservice from within another.
eg: the following method is part of Legal Service
#Autowired
public ServiceManager UserServiceManager;
public void updateUserLegalData(){
//do db update of Legal info for the user
userServiveManager.setAcceptedLegal(true);
}
There are two db transactions going on above. one is updating legalService db and other is updating UserService db. please NOTE userService is a microservicerunning on a separate VM.
we are seeing situations where legal Service db is updated but call to userService is failing (Internal server error). so this leaves the application in an inconsistent state. How can we fix this in a recommended way?
Thanks
This situation can be handled only with JTA global/distributed transactions. JTA is part of Java EE standard and can have various implementors. Atomikos is often tool of choice.
Here is good writeup from Dave Syer (Spring ecosystem contributor). It contain also working examples. It's little bit outdated, but still relevant. You can apply some more modern Spring abstractions on top of his examples.
I created few GitHub examples of JTA transactions for my book. Notice that there are errors simulated and transaction is spread across JMS and JDBC datasources.
But also bear in mind that JTA transactions across various data sources are slow, because of 2-phased commit algorithm involved. So often people try to avoid them and rather deal with inconsistencies somehow pragmatically.
Don't do distributed transactions.
For integration with your existing legacy system one approach could be a separate (micro)service which listens to update events from your userService and forwards the respective updates to the legalService.
Spring integration may be suitable for such a task.
Cheers,
Michael
Well if you read little bit about the subject in the internet, it is a big debacle point at the moment but there is one answer that everybody agrees on it, distributed transactions are not way to go for it. They are too clumsy and buggy that we can't rely on them for data consistency.
So what is our options then, people are the moment trying to coordinate micro service transactions via Apache Kafka or with Event Source (which concentrate on saving events which are changing the data instead of saving the data itself). So what is the problem with those? Well they are quite different then usual programming model that we get used to and at technical and organisational point of view quite complex, so instead of programming for Business Problems, you start programming against the technical challenge.
So what is the alternative, I personally developed an another concept and wrote a blog about it, it might be interesting for you. In its basics, it uses full micro service design principles and Spring Boot + Netflix in a J2EE container and fully using the transactions, it is too long to write all details here, if you are interested you can read the from the link below.
Micro Services and Transactions with Spring Boot + Netflix
Transaction across microservices can become complex and can slow down the system, one of the best ways to solve the problem of distributed transactions is to avoid them completely.
If you avoid distributed transactions across microservices then you will not end up in such situation.
If at all you have to implement distributed transactions across microservices then I think there are a couple of ways :
Two-phase commit protocol
**Eventual Consistency
In your case, I would recommend using message bus and flag to communicate among services , So if legal service adds the data into legal database put a lock on that record and send message on message bus , user service when it is up it will pick the message and update database at its end and send ack message onto the message bus, once ack message is received remove the lock otherwise delete/rollback the record after certain time duration. This looks complex but reliable and failure-proof solution in your case.
I am looking around for a multitenancy solution for my web application.
I would like to implement a application with Separate Schema Model. I am thinking to have a datasource per session. In order to do that i put datasource and entitymanger in session scope , but thats not working. I am thinking to load data-access-context.xml(which include datasource and other repository beans) file when the user entered username and password and tenantId. I would like to know if it is a good solution?
Multitenancy is a bit tricky subject and it has to be handled on the JPA provider side so that from the client code perspective nothing or almost nothing changes. eclipselink has support for multitenancy (see: EclipseLink/Development/Indigo/Multi-Tenancy), hibernate just added it recently.
Another approach is to use AbstractRoutingDataSource, see: Multi tenancy in Hibernate.
Using session-scope is way too risky (also you will end up with thousands of database connections, few for every session/user. Finally EntityManager and underlying database connections are not serializable so you cannot migrate your session and scale your app properly.
I have worked with a number of multi-tenancy systems. The challenge here is how you keep
open architecture and
provide a solution that evolves with your business.
Let's look at second challenge first. Multi-tenancy systems has a tendency to evolve where you'll need to support use cases where same data (record) can be accessed by multiple tenants with different capacity (e.g. https://bugs.eclipse.org/bugs/show_bug.cgi?id=355458). So, the system ultimately needs Access Control List.
To keep the open architecture you can code to a standard (like JPA). Coding to EclipseLink or Hibernate makes me uncomfortable.
Spring Security ACL provides very flexible community supported solution to both these challenges. Give that a try. I did and been happy with it's performance. However, I must caution you, it took me some digging to get my head around it.
Haven't used EJB3, but by reading a tutorial, EJB3 looks like mostly for manipulating data in database through JPA (of course, it contains other business logic). Just curious, if no database is quired, is it still beneficial to use EJB3 or it just adds complexity to an application? Will POJO be a better choice for implementation?
Big part of EJB benefits is coming from transactions and persistence.
But even without them you may benefit from EJBs. It can give you a proven clustering and balancing model. It can give you the declarative security. It can give you MDBs which are a convenient way to listen to JMS queues/topics and timers.
All above can be done using third-party libraries, such as Spring. EJBs though are highly consistent, while to get, for instance, clustering and security you may need to combine two products, and it's not guaranteed they will work together well and won't need much glue.
EJBs are transactional, distributed components deployed on an app server that manages lifecycle, threading, and other services. Persistence is just one type of EJBs. You still might find stateless, stateful, or message EJBs useful, even if you don't want to use entity beans.
With that said, you can create POJO components that are stateful, stateless, persistent or message-driven. You don't need EJBs; something like Spring can be a good alternative.
Is it possible to make XA-transactional access to the file system in Java?
I want to manipulate files within the boundaries of a transaction and my transaction must participate in a distributed transaction via JTA (so I guess the file system needs to be accesses as a XAResource). I don't need support for fine-grained read/write file access; treating each file as a record is good enough for my needs.
Does anybody know an open-source project that already does this? I don't feel like implementing this mess just to find out that it's already been done...
I heard some rumors that JBoss Transcations will add support for this (see for example this discussion) but couldn't find an official statement about this.
By the way, if you need transactional file access but don't require the transaction to participate in a 2-phase commit I recommend you have a look at Apache Commons Transaction
A nice article about the complexities involved can be found in here.
XADisk can get you what you are looking for. It's free and open source.
Recently I solved exactly the same problem. Finally I used Bitronix with XADisk.
You can find more details in my blog post: JTA transaction manager – Atomikos or Bitronix?
At the time the JBoss Transactions intern started there was no XA capable file system driver for Java. I've not checked more recently, but nor have I seen any news about similar work. The work that Ioannis did during his internship is available if you want to use it, but not under active development at present. Unless you want to become an open source contributor :-)
At some point in the future when we have the time and/or customer demand we may roll this functionality into the product. Meanwhile it's at www.jboss.org/jbosstm/fileio/ and the original project discussion is at www.jboss.org/community/wiki/JBossTSProjects
Jonathan Halliday
JBossTS dev team
At Atomikos we did this about 10 years ago but dropped the idea due to lack of demand.
We could resume our efforts if there is sufficient reason to do so.