The difference between global transactions and local transactions

Global Transaction: A transaction managed and coordinated by the resource manager, which can span multiple databases and processes. Resource managers typically use the XA two-phase commit protocol to interact with an Enterprise Information System (EIS) or database. 
Local Transactions: Transactions local to a single EIS or database and restricted to a single process. Local transactions do not involve multiple data sources. 

There are two configuration methods in the Hibernate configuration file:

1. If you are using a local transaction (jdbc transaction)
<property name="hibernate.current_session_context_class">thread</property>, this is our commonly used option, which only operates on one database, that is, only for one transactional 2.
If you are using a global transaction (jta transaction)
<property name="hibernate.current_session_context_class">jta</property>    

    The transaction types we have learned before are all local transactions. What is the difference between JTA (global transaction) and thread (local transaction)? In some applications, only global transactions can be used, for example: 
there are two databases: 
1.mysql 2.oracle now has a business requirement--transfer 
step 1> update mysql_table set amount=amount-xx where id=aaa deduction occurs Money, assuming that the money is deducted from the mysql database. 
step 2> update oracle_table set amount=amount+xx where id=bbb Add money, assuming that the money is deducted from the oracle database. 
Now how do you ensure that both statements are executed in the same transaction? 

It used to be done in JDBC 
connection = mysql connection mysql 
connection.setAutoCommit(false); Do not automatically commit 
1> update mysql_table set amount=amount-xx where id=aaa Deduction occurs, assuming that the deduction is in the mysql database. 
2> update oracle_table set amount=amount+xx where id=bbb occurs in the oracle database 
connection.commit(); 
execute these two statements, and then commit the transaction through the connection object. We can only do this to ensure that these two statements are in the same A database mysql is implemented in the same transaction. But the problem is that we are now connecting to the oracle database, do we need connection2? 

connection = mysql connection mysql 
connection2 = oracle connection oracle 
connection.setAutoCommit(false); Do not commit automatically 
1> update mysql_table set amount=amount-xx where id=aaa Deduction occurs, assuming that the deduction is in the mysql database. 
2> update oracle_table set amount=amount+xx where id=bbb occurs in the oracle database 
connection.commit(); 
connection2.setAutoCommit(false); 
connection2.commit(); 
transactions can only be opened in one connection, and ensure two The statements are all executed in the connection, so that the two statements can be executed in the same transaction. Now the problem is that connection2 is connected to the oracle database, so does it make sense to open the transaction for connection2? Can it be assured? No, so in this case you can only use global transactions. 
In this case, ordinary JDBC operations cannot meet this business requirement. This business requirement can only use global transactions, and local transactions cannot support our operations, because at this time, the life cycle of transactions should not be limited to connection objects. What about the lifetime scope of 

global transactions? 
JPA.getUserTransaction().begin(); First of all, we need the API of the global transaction, we don't need to write it, usually the container has already provided it to us, we only need to begin 
connection = mysql to connect to mysql 
connection2 = oracle 连接oracle 
connection--> update mysql_table set amount=amount-xx where id=aaa 发生扣钱,假设是在mysql数据库扣钱的。 
connection2--> update oracle_table set amount=amount+xx where id=bbb 发生在oracle数据库 
JPA.getUserTransaction().commit(); 

那么它是怎么知道事务该提交还是回滚呢? 
这时候它使用了二次提交协议。二次提交协议简单说就这样:如果你先执行第一条语句,执行的结果先预提交到数据库,预提交到数据库了,数据库会执行这条语句,然后返回一个执行的结果,这个结果假如我们用布尔值表示的话,成功就是true,失败就是false.然后把执行的结果放入一个(假设是List)对象里面去,接下来再执行第二条语句,执行完第二条语句之后(也是预处理,数据库不会真正实现数据的提交,只是说这条语句送到数据库里面,它模拟下执行,给你返回个执行的结果),假如这两条语句的执行结果在List里面都是true的话,那么这个事务就认为语句是成功的,这时候全局事务就会提交。二次提交协议,数据库在第一次提交这个语句时,只会做预处理,不会发生真正的数据改变,当我们在全局事务提交的时候,这时候发生了第二次提交,那么第二次提交的时候才会真正的发生数据的改动。 
   如果说在执行这两条语句中,有一个出错了,那么List集合里就有个元素为false,那么全局事务就认为你这个事务是失败的,它就会进行回滚,回滚的时候,哪怕你的第二条语句在第一次提交的时候是成功的,它在第二次提交的时候也会回滚,那么第一次的更改也会恢复到之前的状态,这就是二次提交协议。(可以查看一下数据库方面的文档来了解二次提交协议)

 

源自:http://blog.csdn.net/sunitjy/article/details/6585301

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326781782&siteId=291194637
Recommended