There are three types of Java transactions: JDBC transaction, JTA (Java Transaction API) transaction, and container transaction. Common container transactions such as Spring transactions. Container transactions are mainly provided by J2EE application servers. Most container transactions are completed based on JTA. This is a JNDI-based, quite complex API implementation. Therefore, this article will not discuss container transactions for the time being. This article mainly introduces two relatively basic transactions in J2EE development: JDBC transaction and JTA transaction.
JDBC transactions
All behaviors, including transactions, of JDBC, are based on a Connection, and transaction management is performed through the Connection object in JDBC. In JDBC, commonly used transaction-related methods are: setAutoCommit, commit, rollback, etc.
Here is a simple JDBC transaction code:
public void JdbcTransfer() { java.sql.Connection conn = null; try{ conn = conn =DriverManager.getConnection("jdbc:oracle:thin:@host:1521:SID","username","userpwd"); // Set the automatic submission to false, //If set to true, the database will recognize each data update as a transaction and automatically submit conn.setAutoCommit(false); stmt = conn.createStatement(); // Reduce the amount in account A by 500 stmt.execute("/ update t_account set amount = amount - 500 where account_id = 'A'"); // Increase the amount in account B by 500 stmt.execute("/ update t_account set amount = amount + 500 where account_id = 'B'"); // Submit transaction conn.commit(); // Transaction commit: The two-step operation of the transfer succeeds at the same time} catch(SQLException sqle){ try{ // An exception occurs, rollback() in this transaction conn.rollback(); // Transaction rollback: The two-step operation of the transfer completely revoke stmt.close(); conn.close(); }catch(Exception ignore){ } sqle.printStackTrace(); } }The above code implements a simple transfer function, which controls the transfer operation through transactions, either submitting or rolling back.
Pros and cons of JDBC transactions
JDBC provides the most basic support for database transaction operations using Java. Through JDBC transactions, we can put multiple SQL statements into the same transaction to ensure their ACID characteristics. The main advantage of JDBC transactions is that the API is relatively simple, can implement the most basic transaction operations, and the performance is relatively good.
However, JDBC transactions have one limitation: a JDBC transaction cannot span multiple databases! ! ! Therefore, if multiple database operations or distributed scenarios are involved, JDBC transactions are powerless.
JTA transactions
Why JTA is needed
Usually, JDBC transactions can solve problems such as data consistency. Given that its usage is relatively simple, many people only know that there are JDBC transactions about transactions in Java, or that some people know about transactions in frameworks (such as Hibernate, Spring), etc. However, since JDBC cannot implement distributed transactions, and there are more and more distributed scenarios today, JTA transactions emerge.
If you do not encounter scenarios that JDBC transactions cannot be solved at work, then you can only say that the projects you are doing are still too small. Take e-commerce websites as an example. We generally split an e-commerce website horizontally into product modules, order modules, shopping cart modules, message modules, payment modules, etc. Then we deploy different modules to different machines, and each module communicates through remote service calls (RPCs) and other methods. Provide services to the outside world with a distributed system.
A payment process must interact with multiple modules, each module is deployed in a different machine, and the databases operated by each module are inconsistent. At this time, JDBC cannot be used to manage transactions. Let's look at a piece of code:
/** Payment order processing**/ @Transactional(rollbackFor = Exception.class) public void completeOrder() { orderDao.update(); // Order service locally updates order status accountService.update(); // Call the fund account service to add points to the fund account pointService.update(); // Call the points service to add points to the points account account account accountingService.insert(); // Call the accounting service to write the accounting system original accounting voucher merchantNotifyService.notify(); // Call the merchant notification service to send payment result notification to the merchant}The above code is a simple payment process operation, in which five services are called, all of which are called through RPC. How to ensure transaction consistency using JDBC? I added the @Transactional annotation to the method, but because of the use of a distributed service, the transaction cannot achieve the effect of ACID.
JTA transactions are more powerful than JDBC transactions. A JTA transaction can have multiple participants, while a JDBC transaction is limited to a single database connection. Components of any of the following Java platforms can participate in a JTA transaction: JDBC connection, JDO PersistenceManager object, JMS queue, JMS topic, enterprise JavaBeans (EJB), and a resource allocator compiled with the J2EE Connector Architecture specification.
Definition of JTA
Java Transaction API (JTA) is a Java enterprise version of application program interface. In the Java environment, it allows distributed transactions across multiple XA resources to be completed.
JTA and its compatriot Java Transaction Service (JTS; Java TransactionService), provide distributed transaction services for the J2EE platform. However, JTA only provides an interface and does not provide a specific implementation. Instead, it is provided by the j2ee server provider according to the JTS specification. There are several common JTA implementations:
1. JTA implementation (JBoss) provided by J2EE container
2. Independent JTA implementations: such as JOTM, Atomikos. These implementations can be used in environments that do not use J2EE application servers to provide distributed transaction guarantees. Such as Tomcat, Jetty and ordinary Java applications.
JTA provides java.transaction.UserTransaction, which defines the following methods.
Here, it is worth noting that ordinary JDBC operations can be directly converted into JTA operations without using UserTransaction. JTA has requirements for DataSource, Connection and Resource. Only classes that comply with the XA specification and implement the relevant interfaces of the XA specification can participate in JTA transactions. Regarding the XA specification, please see the relevant introduction in another article in my article. Here, let me mention that current mainstream databases support XA specification.
To use JTA transactions, 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 JTA transactions. An XADataSource object is a factory of an XAConnection object. XAConnection is a JDBC connection that participates in JTA transactions.
To use JTA transactions, you must use XADataSource to generate the database connection, and the resulting connection is an XA connection.
The difference between XA connection (javax.sql.XAConnection) and non-XA (java.sql.Connection) connection is that XA can participate in JTA transactions and does not support automatic commits.
Sample code:
public void JtaTransfer() { javax.transaction.UserTransaction tx = null; java.sql.Connection conn = null; try{ tx = (javax.transaction.UserTransaction) context.lookup("java:comp/UserTransaction"); //Get JTA transactions, in this case, the Jboss container is managed by javax.sql.DataSource ds = (javax.sql.DataSource) context.lookup("java:/XAOracleDS"); //Get database connection pool, there must be a database and driver that supports XA that supports tx.begin(); conn = ds.getConnection(); // Set the automatic commit to false, //If set to true, the database will recognize each data update as a transaction and automatically submit conn.setAutoCommit(false); stmt = conn.createStatement(); // Decrease the amount in account A by 500 stmt.execute("/ update t_account set amount = amount - 500 where account_id = 'A'"); // Increase the amount in account B by 500 stmt.execute("/ update t_account set amount = amount + 500 where account_id = 'B'"); // Increase the amount in account B by 500 stmt.execute("/ update t_account set amount = amount + 500 where account_id = 'B'"); // Increase the amount in account B by 500 stmt.execute("/ update t_account set amount = amount + 500 where account_id = 'B'"); // commit transaction tx.commit(); // Transaction commit: The two-step operation of the transfer is successful at the same time} catch(SQLException sqle){ try{ // An exception occurs, rollback() in this transaction; // Transaction rollback: The two-step operation of the transfer is completely revoked stmt.close(); conn.close(); } catch(Exception ignore){ } sqle.printStackTrace(); } } The above example is a transfer operation using JTA transactions. This operation is relatively dependent on the J2EE container and requires the userTransaction and Connection to be obtained through JNDI.
Standard distributed transactions
A distributed transaction includes a transaction manager and one or more resource managers. A resource manager is a persistent data store of any type. The transaction manager assumes the responsibility for communication between all transaction participants.
Look at the above introduction to distributed transactions, is it similar to transaction management in 2PC? However, 2PC is actually an implementation method for a transaction manager that complies with the XA specification to coordinate multiple resource managers. I have had several articles on 2PC and 3PC before. In those articles, I have introduced how the transaction manager in distributed transactions coordinates the unified commit or rollback of multiple transactions. I will also introduce in detail the content related to distributed transactions, including but not limited to global transactions, DTP models, flexible transactions, etc.
Pros and cons of JTA
The advantage of JTA is that it provides a distributed transaction solution and strict ACID. However, the standard JTA transaction management is not commonly used in daily development because it has many shortcomings:
Implementation complex
Normally, JTA UserTransaction needs to be obtained from JNDI. This means that if we use JTA, we need to use both JTA and JNDI.
JTA itself is a bulky API.
Usually JTA can only be used in application server environments, so using JTA will limit the reusability of the code.
Summarize
There are three types of Java transactions: JDBC transaction, JTA (Java Transaction API) transaction, and container transaction. Among them, JDBC's transaction operation usage is relatively simple and suitable for handling operations of the same data source. JTA transactions are relatively complex and can be used to handle transactions across multiple databases. They are a solution for distributed transactions.
Let me briefly talk about it here. Although JTA transactions are a set of APIs provided by Java for distributed transactions, different J2EE platforms have different implementations and are not very convenient to use. Therefore, this more responsible API is generally not used in projects. The distributed transaction solutions commonly used in the industry now include asynchronous message assurance, TCC, maximum effort notification, etc.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.