The previous article introduced the JDBC transaction, JDBC can handle the transaction of a single data source, satisfies most transaction processing requirements, but the JDBC transaction does not solve the problem of multi-data source and distributed transaction, the Java platform provides us with solution--jta. This article will explore some of the details of JTA.
A distributed transaction
Typically, a transaction within a database, such as operations on multiple tables, is treated as a local transaction. The transaction objects for the database and JDBC are local transactions, while the Distributed transaction objects are global transactions.
The so-called global transactions, refers to the Distributed transaction processing environment, multiple databases may need to work together to complete a task, which is a global transaction, for example, a transaction may update several different databases. Operations on the database occur throughout the system, but must all be committed or rolled back. At this point, the submission of a database to its internal operations depends not only on the success of the operation itself, but also on the success of the operation of other databases related to the global transaction, and if any one of the databases fails, all the operations of the database participating in the transaction must be rolled back.
In general, a database cannot know what other databases are doing, so in a DTP environment, transactional middleware is required to notify and coordinate the submission or rollback of related databases. A database only has its own operations (recoverable) mapped to global transactions, which is a distributed transaction processing model.
Two XA specification
The X/open organization (now the Open group) defines a distributed transaction processing model. The X/open DTP Model (1994) includes the application (AP), transaction manager (TM), Resource Manager (RM), Communications Explorer (CRM) four section.
A common transaction manager (TM) is a transactional middleware, such as the TransactionManager provided by JDBC or hibernate, and a common resource manager (RM) is a database, typically a data source, such as a JDBC or third-party datasource. A common Communication Resource Manager (CRM) is message middleware, such as JMS.
The typical DTP model is as follows:
Three JTA Realization
As an example of the transfer of funds previously mentioned, we illustrate the specific implementation of JTA.
<span style= "FONT-SIZE:18PX;" > public void Transferaccount () {usertransaction usertx = null; Connection Conna = null; Statement Stmta = null; Connection CONNB = null; Statement STMTB = null; try{//Get Transaction Management Object USERTX = (usertransaction) getcontext (). Lookup ("Java:comp/usertransaction"); Get database connection from database A Conna = Getdatasourcea (). getconnection (); Get the database connection from database B CONNB = Getdatasourceb (). getconnection (); Start transaction usertx.begin (); Reduce the amount in a account by up to Stmta = Conna.createstatement (); Stmta.execute ("update t_account set amount = amount-500 where account_id = ' A '"); Increase the amount in the B account by $ stmtb = Connb.createstatement (); Stmtb.execute ("update t_account Set amount = Amount + where account_id = ' B '"); Commit Transaction Usertx.commit (); Transaction commit: The two-step operation of the transfer succeeds at the same time (data in database A and database B is updated simultaneously)} catch (SQLException Sqle) {try{//exception, rollback of manipulation in this transaction Usertx.rollback (); Transaction rollback: Two-step operation of the transfer is completely revoked//(numberData updates in library A and database B are simultaneously revoked) stmt.close (); Conn.close (); ... } catch (Exception ignore) {} sqle.printstacktrace (); } catch (Exception ne) {e.printstacktrace (); }}</span>
Note: In the example above, we used two databases, that is, Conna and CONNB are connections from different databases.
Four JTA Realization principle
How does JTA actually implement the transaction manager? To understand the JTA implementation principle, you need to understand its schema first: It includes the transaction manager (Transaction Manager) and one or more XA protocol-supporting resource managers (Resource Manager), we can view the resource Manager as any type of persisted data Storage; The transaction manager is responsible for the coordination and control of all the transaction participation units. Depending on the object-oriented, we can understand the JTA transaction manager and the resource manager as two aspects: the usage interface (transaction manager) for the developer and the implementation interface (Resource Manager) for the service provider. The main part of the development interface is the UserTransaction object referenced in the example above, in which the developer implements the distributed transaction in the information system, and the implementation interface is used to standardize the transaction service provided by the provider (such as the database connection provider), which contracts the resource management function of the transaction. Enables JTA to perform collaborative communication between heterogeneous transaction resources. In the case of databases, IBM provides a database driver for distributed transactions, and Oracle provides a database driver for distributed transactions, while simultaneously using DB2 and Oracle two database connections, JTA That is, you can implement distributed transactions based on the two transactional resources of the agreed interface coordinator. It is the different implementations that are based on uniform specifications that enable JTA to coordinate and control transactional resources for different databases or JMS vendors, as shown in the architecture:
developers use the developer interface to enable application support for global transactions; each provider (database, JMS, etc.) provides transactional resource management capabilities based on the specifications of the provider interface; transaction manager ( TransactionManager) maps the use of distributed transactions to the actual transactional resources and coordinates and controls the transaction resources. Here, the three main interfaces, including UserTransaction, Transaction, and TransactionManager, as well as their defined methods, are described in this article.
developer-oriented interfaces are usertransaction (using the method shown in the example above), and developers typically use this interface only to implement JTA transaction management, which defines the following methods:
begin ()-Start a distributed transaction
commit ()-Commit transaction
rollback ()-Rollback TRANSACTION
getStatus ()-Returns the status of the distributed transaction associated to the current thread
setrollbackonly ()-Identifies a distributed transaction that is associated to the current thread will be rolled back
the provider-oriented implementation interface mainly involves TransactionManager and Transaction two objects
Transaction represents a physical transaction, and TransactionManager creates a Transaction when the developer calls the Usertransaction.begin () method. The transaction object (which marks the beginning of the transaction) and associates this object to the current thread through Threadlocale. Methods such as commit (), rollback (), getStatus () in the UserTransaction interface are ultimately delegated to the corresponding method of the Transaction class.
registersynchronization (Synchronization Sync)-callback interface, Hibernate and other ORM tools have their own transaction control mechanism to guarantee transactions, but they also need a callback Mechanism to be notified when a transaction completes, triggering some processing work, such as clearing the cache, and so on. This involves the callback interface registersynchronization of the Transaction. The tool can inject the callback program into the transaction through this interface, and when the transaction is successfully committed, the callback program is activated.
TransactionManager itself does not assume the actual transaction processing function, it is more to act as a bridge between the user interface and the implementation interface. The methods defined in TransactionManager are listed below, and you can see that most of the transaction methods in this interface are identical to UserTransaction and Transaction. When the developer calls the Usertransaction.begin () method, TransactionManager creates a Transaction transaction object (which marks the beginning of the transaction) and associates the object with Threadlocale on the current thread The same usertransaction.commit () will call Transactionmanager.commit (), which will fetch the transaction object Transaction from the current thread and commit the transaction represented by the object, that is, invoking the Transaction.commit ()
The following will introduce the JTA implementation principle to the reader through specific code. Lists the Java classes involved in the example implementation, where Usertransactionimpl implements the UserTransaction interface, Transactionmanagerimpl implements the TransactionManager interface, Transactionimpl implements the Transaction interface
The JTA implementation class diagram is as follows:
Why is a database connection that must be obtained from a data source that supports transactions to support distributed transactions? In fact, the data source supporting the transaction is different from the normal data source, it implements the additional Xadatasource interface. We can simply interpret xadatasource as a normal data source (inherited from Java.sql.PooledConnection), but it adds Getxaresource methods to support distributed transactions. In addition, the database connection returned by Xadatasource is also different from the normal connection, which implements the Xaconnection interface in addition to all the functions defined by the java.sql.Connection. We can understand xaconnection as a normal database connection, which supports database operations for all JDBC specifications, except that xaconnection adds support for distributed transactions. The following class diagram readers can understand the relationship of these interfaces:
The database connection that an application obtains from a data source that supports distributed transactions is an implementation of the Xaconnection interface, and the session created by this database connection (Statement) also adds functionality to support distributed transactions, as shown in the following code:
JTA Transaction Resource Processing
<span style= "FONT-SIZE:18PX;" >public void Transferaccount () { usertransaction usertx = null; Connection conn = null; Statement stmt = null; try{ //Get Transaction Management Object USERTX = (usertransaction) getcontext (). Lookup ("java:comp/usertransaction");// To get the database connection from the database, GETDATASOURCEB returns the data source that supports the distributed transaction conn = Getdatasourceb (). getconnection (); Session stmt has been enhanced to support distributed transactions stmt = Conn.createstatement (); Start transaction Usertx.begin (); Stmt.execute ("Update t_account ... where account_id = ' A '"); Usertx.commit ();} catch (SQLException Sqle) { //Handle exception code} catch (Exception ne) { e.printstacktrace (); } } </span>
Five Summary
The implementation of JTA is actually derived from the JDBC transaction, JTA is different from JDBC: The resource manager needs to implement Xadatasource interface, as long as this interface is implemented, transaction management can be realized through JTA transaction manager.
Java Transaction--JTA principle