Could someone clarify the difference between one-phase and two-phase commit. As far as I understand one-phase commit represents commit in the course of application server (Service method -> EntityManager) and XA commit is the same transaction up to the database (Service method -> EntityManager -> DB) and is used in order to properly rollback overall transaction. So why don't we use XA drivers by default? Is this just performance concern? Please correct me if I'm wrong.
The difference is that one-phase commit is usually used within one system or database while two-phase commit is used for distributed transactions which span multiple DBs or systems. Let me show you simple example for each
One-phase commit
BEGIN
INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (1, 'Ramesh', 32, 'Ahmedabad', 2000.00 );
INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (2, 'Khilan', 25, 'Delhi', 1500.00 );
COMMIT;
This is classic atomic transaction written in PL/SQL (for Java EE world, imagine EJB method which can be transactional too), there is just one phase where all actions are performed and either the commit or rollback is made.
Two-phase commit
//pseodocode
BEGIN
UPDATE db1; //updates DB on another machine
UPDATE someCloudStorage; //update something on the cloud
INSERT INTO SomeTable VALUES(...);
COMMIT;
Now you are dealing with different systems on different machines but you want to write successfully to all of them or fail (that's why it's a distributed transaction). So here comes the Two-phase commit protocol. Basically transaction manager broadcasts "prepare for commit" message and then waits for OK response from each machine. If everybody says it's "okay", everything gets committed - if not, all transactions are rolled back.
Note that if you want to use XA transactions in Java, you will need a JDBC driver with XA support (and properly configured XA datasource).