[JAVAEE-JPA] 3. Transaction management in the Spring framework

Source: Internet
Author: User

This article discusses how transaction partitioning (Transaction demarcation) is implemented in EJBs, and continues to describe how transaction partitioning is done in the spring framework.

We already know that when using container transaction types, there are two main scenarios for transaction partitioning (see here):

    1. Using the JTA interface to encode in an application to complete explicit partitioning
    2. Automatic partitioning with the help of a container

When using the Java EE EJB specification, the two scenarios were implemented as BMT and CMT, and the BMT and CMT were discussed in more detail in the previous article (see here).

So how do you implement both of these scenarios for the spring framework?

One of the main advantages of the Spring framework is that it masks many of the implementation details of the underlying container, and it even does some encapsulation on top of the Java EE Standard to maximize platform-independent, container-independent. When developing Java EE applications using the spring framework, the dependency on the underlying containers is not obvious. Therefore, it does not have to rely heavily on the JTA specification when using container-based transaction types as EJBS do. It accomplishes the partitioning of transactions by providing the following two implementation scenarios:

    1. Declarative transaction management (declarative Transaction Management)
    2. Programmatic transaction management (programmatic Transaction Management)

Although the name is different, but the essence is similar.

The first, declarative transaction management, is designed to help developers complete the automatic partitioning of transactions. This is very similar to EJB CMT. The second, programmatic transaction management, is designed to allow developers to have a way to control how a transaction should proceed. This is very similar to EJB BMT.

Spring Framework Transaction Management Overview

Before you introduce the specific declarative and programmatic two transaction management scenarios, you need to briefly explain how the spring framework manages transaction management.

In traditional Java EE, developers can generally use two types of transactions:

    1. Resource-local Local Transactions
    2. Global transaction (typically requires application server-provided container environment, so also known as container transaction)

For local transactions, there is no way to target multiple transactional resources, often only for a single transactional resource. And it's too low-level, very intrusive for business logic, and it's written by a JDBC-based application that it's possible that only 5 lines in 20 lines of code are business-related, and that the remaining 15 lines are used to handle transactions and related exceptions. So the code is hard to maintain and looks less elegant.

For global transactions, it overcomes the drawbacks of local transactions and is capable of handling multiple transactional resources (typically, such as databases, message queues, and so on). But it relies on the cumbersome JTA (Java Transaction API), a set of transaction-related APIs that are complain incessantly, similar to JDBC, and have too much of an underlying problem. More importantly, JTA is generally the service that the application server will provide, so the conditions for using global transactions are more stringent.

So for all the pain points above, the Spring framework sets up a set of abstractions about transactions. Enables developers to easily use transactions to manage resources in any environment. Even in general, even the application server is not required, using a generic web container, such as popular Tomcat (only if you need to handle multiple transactional resources at the same time, you may need to use the application server, but the general application is obviously less complex).

The Spring framework's abstraction of transactions

The Spring framework builds this abstraction by introducing a concept called a transaction policy (Transaction strategy). Specifically, this interface is shown below:

publicinterface PlatformTransactionManager {    throws TransactionException;    voidthrows TransactionException;    voidthrows TransactionException;}

org.springframework.transaction.PlatformTransactionManagerAn interface is essentially a service provider Interface (Services Provider Interface, SPI). This is also a system to achieve the scalability of a classic design mode, specific reference to Wikipedia. For example, the JDBC we know is dependent on this pattern, and various database vendors implement the functions in the JDBC SPI so that their databases can communicate with the Java application.

Each method defined in the interface may throw a named exception, which is not the exception TransactionException defined in JTA's related interface, which is essentially a Checked Exception, but TransactionException a runtime exception (runtime Exception). This also reflects the design principles of the spring framework, as much as possible without messing up developers. After all, dealing with transaction-related exceptions is not an easy job. Generally it is directly thrown out, who has the ability to deal with WHO. So here the exception is defined as the runtime exception by default the developer will not handle it, but if you have the ability to handle it, add the Try...catch statement.

Here is a brief introduction to the three methods in the above interfaces:

throws TransactionException;

There are two new concepts appearing here.
The accepted parameter is an TransactionDefinition interface, and the returned object is an TransactionStatus interface.

In the documentation for the TransactionDefinition interface, there is a passage:

Interface that defines spring-compliant transaction properties.
Based on the propagation behavior definitions analogous to EJB CMT attributes.

This interface defines spring-compatible transaction properties. These properties are similar to the definition of transaction propagation (Transaction propagation) behavior in EJB CMT. And this transactional communication actually refers to @TransactionAttribute those attributes defined in, such as,, MANDATORY REQUIRED REQUIRES_NEW etc., the details can be referred to here.

With that in mind, take a look at what's in the definition:

 Public  interface transactiondefinition {    //Propagate property    intpropagation_required =0;intPropagation_supports =1;intPropagation_mandatory =2;intPropagation_requires_new =3;intpropagation_not_supported =4;intPropagation_never =5;intpropagation_nested =6;//Isolation Properties    intIsolation_default =-1;intisolation_read_uncommitted = connection.transaction_read_uncommitted;intisolation_read_committed = connection.transaction_read_committed;intIsolation_repeatable_read = Connection.transaction_repeatable_read;intisolation_serializable = connection.transaction_serializable;//Timeout Property    intTimeout_default =-1;//Behavior    intGetpropagationbehavior ();intGetisolationlevel ();intGetTimeout ();BooleanIsReadOnly (); String getName ();}

As you can see, this interface defines a variety of properties, as well as a way to get a transactional property. So the purpose of this interface as a getTransaction parameter of the above method is clear: To obtain a specific transaction based on the properties of the transaction described. It is like passing in a config object to get an object that conforms to the config definition.

Then, what does the method return TransactionStatus :

public  interface  transactionstatus  extends  savepointmanager ,     Flushable  { boolean  isnewtransaction ();    boolean  hassavepoint ();    void  setrollbackonly ();    boolean  isrollbackonly ();    void  flush (); boolean  iscompleted ();}  

This is obvious, and it is very similar to the previously introduced JTA, which provides a high degree of similarity in the implementation of BMT UserTransaction . It represents a specific transaction object that is associated with a current execution thread. Depending on the TransactionDefinition transaction attribute defined, the specific transaction object can be a transaction object that was just created (when the propagation attribute is defined as PROPAGATION_REQUIRES_NEW ), or it can be reused (when the propagation property is defined as PROPAGATION_SUPPORTS or is PROPAGATION_REQUIRED actually running in a transactional environment).

The two remaining methods in the Platformtransactionmanager interface commit() and the look of the rollback() names will know how they are used, so they are no longer introduced.

The implementation of the Platformtransactionmanager interface needs to be injected into the runtime environment, such as jta,jdbc,hibernate, depending on the specific environment. For specific injection methods you can refer to the documentation for the spring framework, which is not detailed here.

Declarative transaction management (declarative Transaction Management)

It is worth integrating that the Spring framework implements declarative transaction management through AOP (aspect-oriented programming, aspect-oriented programming) technology. For AOP, refer to Wikis if you want to learn more.

In fact, the spring framework in the implementation of declarative transaction management, how much also borrowed some of the implementation of the EJB CMT, take its essence to its dross. Then compare it to the EJB CMT, there are mainly the following aspects of improvement:

    1. No longer confined to JTA like EJB CMT. The Spring framework provides declarative transaction management that can run in almost any major environment, such as Jta,jdbc,hibernate. What developers need to do is to provide the appropriate configuration based on the underlying environment.
    2. You can use declarative transaction management for any class, not just a limited number of types like EJB CMT, such as @Stateful @Stateless session beans.
    3. A rollback occurs when a declarative rollback rule, such as specifying which types of exceptions are thrown. This feature is not present in the EJB CMT.
    4. Customize transactional behavior with AOP technology, such as executing custom code when a transaction rolls back. The only thing you can do in EJB CMT for rollback is to call setRollbackOnly() .

The closest thing to EJB CMT is that they trigger a rollback operation when a runtime exception occurs (runtime Exception), but there is no proactive rollback of the exception being inspected (Checked Exception), and the general understanding is that developers need to handle it, Perform a rollback operation explicitly in a catch statement.

That's so nice, so how to use declarative transaction management. In fact, the usage is very simple, just two steps (take the annotation configuration as an example):
1. @Configuration using @EnableTransactionManagement in the Javaconfig class
2. Use on classes or methods that need to use transactions@Transactional

To understand how it is implemented, you first need to understand the concept of AOP proxy. That is, after the developer declares @Transactional , the Spring framework uses AOP technology to generate a proxy object that uses TransactionInterceptor and is combined PlatformTransactionManager to implement the related functions of the transaction.

You can use the following diagram to indicate:

Only the two parts of the caller and target method exist in the spring framework before it is involved. After intervention, using AOP and dynamic agent technology to create a proxy object for the object of the method, and then generate various AOP tasks according to the configuration, such as the transaction advisor in and other types of advisor (log tasks, etc.). Then, when a method call actually occurs, the order of the call is as follows in the number 1-8. When the transaction advisor is executed (step 2), the transaction is actually created and then the business logic is executed in step 4. The execution process is then returned, and the transaction is committed or rolled back according to the success of step 7.

For specific XML and annotation-based configuration methods, you can review the documentation for the Spring Framework transaction section.

Programmatic transaction management (programmatic Transaction Management)

The Spring framework provides two ways to support programmatic transaction management:

    1. TransactionTemplate
    2. PlatformTransactionManager

It is recommended to use the first method. TransactionTemplateformally similar to what is provided in spring JDBC JdbcTemplate , encapsulates a lot of template code, allowing developers to focus on the development of business logic. The second type is similar to that provided in JTA UserTransaction , but simplifies partial exception handling.

Use TransactionTemplateComplete programmatic transaction Management

Here is a snippet of code that uses TransactionTemplate the completed programmatic transaction management (excerpt from the Spring Framework official documentation below):

 Public  class simpleservice implements Service {    //Shared Transactiontemplate instances    Private FinalTransactiontemplate transactiontemplate;//using the constructor injection to inject the implementation of Platformtransactionmanager into the class     Public SimpleService(Platformtransactionmanager TransactionManager) {Assert.notnull (TransactionManager,"The ' transactionmanager ' argument must not be null."); This. transactiontemplate =NewTransactiontemplate (TransactionManager); } PublicObjectSomeservicemethod() {returnTransactiontemplate.execute (NewTransactioncallback () {//The code in this method executes in the context of the transaction             PublicObjectdointransaction(Transactionstatus status) {UpdateOperation1 ();returnResultOfUpdateOperation2 ();    }        }); }}

The style of the callback is used to complete the programmatic transaction management, where the key is the TransactionCallback anonymous implementation of the class, which is passed into TransactionTemplate the Execute method as a parameter.

If the transaction-related code does not return a value, the anonymous implementation of the class without parameters can be used TransactionCallbackWithoutResult .

transactionTemplate.execute(new TransactionCallbackWithoutResult() {    protectedvoiddoInTransactionWithoutResult(TransactionStatus status) {        try {            updateOperation1();            updateOperation2();        catch (SomeBusinessExeption ex) {            // 发生异常时,回滚事务            status.setRollbackOnly();        }    }});
Use PlatformTransactionManagerComplete programmatic transaction Management

Transaction management can be PlatformTransactionManager done with the following logic after the acquired implementation:

new DefaultTransactionDefinition();// 只有在编程式事务管理中才能设置事务的名称def.setName("SomeTxName");def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);TransactionStatus status = txManager.getTransaction(def);try {    // 执行业务逻辑}catch (MyException ex) {    txManager.rollback(status);    throw ex;}txManager.commit(status);
Summarize

This article provides a brief introduction to transaction management in the spring framework. It is how to create an abstraction layer that is independent of the underlying environment and how to use declarative/programmatic to accomplish transaction management. The introduction is relatively brief and the information is referenced from the Spring Framework official documentation. If you need specific configuration methods and more examples, you can refer to the above documents directly.

[JAVAEE-JPA] 3. Transaction management in the Spring framework

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.