Global transactions: Resource Manager manages and coordinates transactions that can span multiple databases and processes. The resource manager typically interacts with an enterprise information System (EIS) or database using the XA two phase commit protocol. Local transaction: A transaction that is local to a single EIS or database and is restricted within a single process. A local transaction does not involve multiple data sources. There are two configuration options in Hibernate configuration files:1If you are using a local transaction (JDBC Transaction)<property name= "Hibernate.current_session_context_class" >thread</property>, this is a common option that operates on only one database, i.e. only one transactional resource.2If you are using a global transaction (JTA Transaction)<property name= "Hibernate.current_session_context_class" >jta</property>The types of transactions we learned previously were local transactions. What is the difference between JTA (global transaction) and thread (local transaction)? In some applications, you can use only global transactions, such as: There are two databases:1.mysql 2.oracle There is now a business need--Transfer Step1> Update mysql_table set amount=amount-xx where id=AAA happens to deduct money, assuming it is deducted at the MySQL database. Step2> Update oracle_table set amount=amount+xx where id=BBB adds money, assuming it's deducted from the Oracle database. Now how do you make sure that two statements are executed in the same transaction? I used to do this in JDBC, connection .=MySQL connection mysql connection.setautocommit (false); Do not submit automatically1> Update mysql_table set amount=amount-xx where id=AAA happens to deduct money, assuming it is deducted at the MySQL database. 2> Update oracle_table set amount=amount+xx where id=The BBB occurs in the Oracle Database Connection.commit (), executes the two statements, and then commits the transaction through the connection object. We can only make sure that these two statements are implemented in the same database MySQL within the same transaction. But the problem is that we are now connecting to the Oracle database, is it necessary to connection2? Connection=MySQL connection mysql connection2=Oracle connects Oracle Connection.setautocommit (false); Do not submit automatically1> Update mysql_table set amount=amount-xx where id=AAA happens to deduct money, assuming it is deducted at the MySQL database. 2> Update oracle_table set amount=amount+xx where id=BBB occurs in Oracle database Connection.commit (); Connection2.setautocommit (false); Connection2.commit (); Transactions can only be opened in one connection, and make sure that two statements are executed in the connection, so that two statements can be executed in the same transaction, and now the problem is that Connection2 is connected to the Oracle database. So does it make sense for Connection2 to open a business again? Can it be ensured? No, so in this case you can only use global transactions. In this case, the normal JDBC operation is not sufficient for this business requirement, this business requirement can only use the global transaction, the local transaction is unable to support our operation, because at this time, the transaction life cycle should not be limited to the life cycle scope of the Connection object global transaction How to do? Jpa.getusertransaction (). Begin (); First of all the global transaction API, do not need us to write, usually the container has been provided to us, we just need to begin connection=MySQL connection mysql connection2=Oracle Connect Oracle Connection--Update mysql_table set AMOUNT=AMOUNT-XX where id=AAA happens to deduct money, assuming it is deducted at the MySQL database. Connection2--Update oracle_table set amount=amount+xx where id=BBB occurs in Oracle Database Jpa.getusertransaction (). commit (); So how does it know that a transaction should be committed or rolled back? At this time it used two commit protocols. Two commits the protocol simply says: If you execute the first statement first, the result of the execution is pre-committed to the database, pre-committed to the database, the database executes the statement, and then returns a result of the execution, if we are represented by a Boolean value, the success is true, Failure is false. Then put the results of the execution into a (assuming a list) object inside, then execute the second statement, after executing the second statement (also preprocessing, the database does not really implement the data to commit, just say that the statement sent to the database, it simulated execution, to return to you the results of execution), if the two words If the execution result of a sentence is true in the list, then the transaction considers the statement to be successful, and the global transaction commits. Two commits the protocol, the database in the first commit this statement, will only do preprocessing, no real data changes, when we commit in the global transaction, this time a second commit, then the second time the submission of the real data change. If there is an error in executing these two statements, then there is an element in the list set that is false, then the global transaction thinks that your transaction is a failure, it will roll back, roll back, even if your second statement is successful at the time of the first commit, It will also roll back at the time of the second commit, so the first change will revert to the previous state, which is the two commit protocol. (You can review the database documentation to learn about two commit agreements)
Transactions-local and global transactions