1. Concepts related to distributed transactions
Distributed transaction processing (distributed Transaction PROCESSING,DTP) refers to the possibility that a transaction may involve multiple database operations, and the key to distributed transaction processing is that there must be a way to know all the actions of a transaction anywhere. Decisions that commit or roll back a transaction must produce a uniform result (commit all or roll back all).
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. Generally, the common transaction manager (TM) is the transaction middleware, the common Resource Manager (RM) is the database, the common Communication Resource Manager (CRM) is the message middleware.
Typically, a transaction within a database, such as operations on multiple tables, is treated as a local transaction. The transaction object for the database is a local transaction, while the distributed transaction object is a global transaction.
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 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 alludes its own operations (recoverable) to global transactions. XA is the interface specification (i.e. interface function) between the transaction middleware defined by the X/open DTP and the database, which is used by the transaction middleware to inform the start, end, and commit, rollback, etc. of the database transaction. XA interface functions are provided by the database vendor.
XA vs. two phase commit protocol
Usually, the transaction middleware and database through the XA interface specification, using two-phase commit to complete a global transaction, the basis of the XA specification is a two-phase commit protocol.
In the first phase, the transaction middleware requests that all relevant databases be ready to submit (pre-commit) their respective branch of the transaction to confirm that all relevant databases can submit their own transaction branches. When a database receives a pre-commit, if it can commit its own branch of the transaction, then the operation of its own in the branch of the transaction is fixed record and give the transaction middleware a consent to commit the answer, the database will no longer be able to add any operations in the transaction branch, but the database does not actually commit the transaction, The database operation on the shared resource has not been released (locked). If for some reason the database cannot submit its own transaction branch, it will roll back all its operations, release the lock on the shared resource, and return the failed response to the transactional middleware. In the second phase, the transactional middleware examines the pre-commit results returned by all databases, such as all databases can be submitted, and the transactional middleware will require all databases to be formally committed so that the global transaction is committed. If any of the database pre-commit returns fail, the transaction middleware will require all other databases to roll back their operations so that the global transaction is rolled back.
Taking a global transaction as an example, the AP first notifies the transaction middleware to start a global transaction, and the transaction middleware notifies the database to start the transaction through the XA interface function, then the AP can manipulate the database-managed resources, and the database system records all the operations of the transaction on the local resource. After the operation is completed, the transaction middleware notifies the database operation through the XA interface function. The transaction middleware is responsible for documenting which databases the AP has operated on (the transaction branch). As the AP informs the transaction middleware to submit the global transaction, the transaction middleware will require each database to be pre-committed through the XA interface function, and all the databases are returned successfully requiring each database to be formally committed, at which point a global transaction ends.
The greatest benefit of the XA specification is that transaction integrity is controlled by the transaction middleware and the database through the XA interface, and the AP only needs to focus on the processing of the application logic of the database, without worrying too much about the integrity of the transaction and simplifying the application design development.
Specifically, if there is no transaction middleware, the application system needs to notify the database start, end, and commit transactions directly inside the program, and when an exception occurs, the database must be reversed by a specialized program to complete the rollback. If it is a global transaction with many transactional branches, the situation becomes unusually complex when rolling back. With the XA interface, the commit of the global transaction is controlled by the transaction middleware, and the application simply notifies the transaction middleware to commit or rollback the transaction, and it can control all commits or rollbacks of the entire transaction (which may involve multiple offsite databases), and the application does not have to consider the flush logic at all.
In a global transaction involving multiple databases, it is necessary to make two-phase submissions from the transactional middleware control database in order to ensure the integrity of the global transaction. A typical two-phase commit, however, is a relatively lengthy transaction from start to finish (commit or rollback) for a database, the resources used by the database during a transaction (such as logical logs, various locks), and is not released until the end of the transaction. Therefore, using a typical two-phase commit will take up more resources, and the network conditions are not very good, such as low-speed nets, network bumps frequently, the situation will be more serious.
When a global transaction involves only a single database, there is an optimization method, that is, a phase commit. When the AP notifies the transaction middleware to commit the transaction, the transaction middleware directly requests the database to commit the transaction, eliminating the first phase in the two-phase commit, which can shorten the time of processing a transaction to improve the efficiency of transaction processing. As a special case of a two-phase commit, a one-phase commit is also standard, as with two phases.
Requirements for XA
For JMS, you need to configure connection factory that supports XA.
For DB, you need to use a JDBC driver that supports XA.
two phase commit (2 phase Commit)
First, the management of transaction, the following figure.
Transaction manager interacts with different resource manager.
At Phase1, transaction manager asked two resouce if they were ready to submit. Resouce can reply to ready, Not_ready or READ_ONLY. When two are ready, you can enter PHASE2 to commit. Any one reply Not_ready the entire transaction rollback. The resources for replying to READ_ONLY are excluded from the commit process during the PHASE2 phase.
2.JTA
JTA (Java Transaction API) provides distributed transaction services for the EE platform.
To use JTA for transaction demarcation, the application calls methods in the Javax.transaction.UserTransaction interface.
Let's take a look at the following words:
"To define transactions with JTA, you need a JDBC driver that implements the Javax.sql.XADataSource, Javax.sql.XAConnection, and Javax.sql.XAResource interfaces. A driver that implements these interfaces will be able to participate in the JTA transaction. A Xadatasource object is a factory of a Xaconnection object. Xaconnection S is a JDBC connection that participates in JTA transactions. ”
To use JTA transactions, you must use Xadatasource to generate a database connection, resulting in a connection that is an XA connection.
The difference between XA connections (javax.sql.XAConnection) and non-XA (java.sql.Connection) connections is that XA can participate in JTA transactions and does not support autocommit. Note:
Large databases such as Oracle, Sybase, DB2, SQL server,mysql (5.0 after InnoDB storage engine) support XA and distribute transactions.
transactions implemented in 3.OFBiz
OFBiz uses Apache Commons dbcp as a database connection pooling technology, and distributed transactions are implemented through Apache Geronimo transaction. The following is a partial implementation of a class relationship:
Both Transactionfactory and ConnectionFactory can be implemented on their own and configured in Entityengine.xml, which is configured by default in OFBiz Geronimotransactionfactory and Dbcpconnectionfactory. Implementing transactions in OFBiz does not require a display call, The service in Services.xml is configured with a configuration of two require-new-transaction and use-transaction, whether a new transaction is started and whether the transaction is enabled, the default is false and true. If you do not implement Service,event for Java, you need to implement the transaction manually, usually as follows:
try {
Begantransaction = Transactionutil.begin (default_tx_timeout);
DB operation
Return "Success";
} catch (Exception e) {
E.printstacktrace ();
Transactionutil.rollback (Begantransaction, E.getmessage (), E);
return "error";
} finally {
Transactionutil.commit (begantransaction);
}