Spring Learning Notes (iv)--A comprehensive analysis of spring affairs

Source: Internet
Author: User
Tags aop rollback savepoint

With the introduction to spring from this series of articles, we have a preliminary understanding of the use of spring and the two core features of the IOC, AOP, and the combination of my personal work, since the project is a finance department

, that control of the transaction is essential, and is very strict control. According to my research on the project, it uses the JTA transaction in the management module, but in the transaction module uses the JDBC matter

, however, the use of all these transactions is a programmatic transaction with spring encapsulated. After watching spring in action, I looked online at the understanding of spring affairs,

There seems to be no real article to fully analyze spring's support for these matters, so write down this blog post to feed everyone.

Tips : This blog will teach the management features of spring transactions, including programmatic and declarative transactions. By understanding this blog post, you will be able to understand the essence of spring transaction management and apply

Of But Ben Boven assumes you have mastered the basics of Java, and you have some knowledge of spring, and if you are not familiar with spring, please refer to the article in this series. You will also need a

Have a certain common sense of transaction management, such as the boundaries of the transaction, the level of isolation and so on. This article will directly exercise these concepts without making specific explanations.


The most important APIs for Spring transaction management are three: Transactiondefinition, Platformtransactionmanager, Transactionstatus. The so-called transaction management, is actually "press

Perform a commit or rollback operation according to the given transaction rule. "A given transaction rule" is expressed in transactiondefinition, "in accordance with ... To perform a commit or rollback operation.

Platformtransactionmanager to indicate that Transactionstatus is used to represent the state of a running transaction.


Spring Transaction attribute profiling

Transaction control is important to the enterprise system. It guarantees that the user's every operation is reliable, even if there is an exception, it will not damage the integrity of the background data. It's like the bank's self-help pick.

Section machine, often on the normal day for the customer officer, but also unavoidably encountered during the operation of the situation of downtime, at this time, the transaction must ensure that the operation of the account before the problem does not take effect, as the user just did not

Have used a cash machine to guarantee the interests of the user and the bank to be protected from loss. In spring, transactions are defined through the Transactiondefinition interface. This interface contains a property with a

The method of closing, as shown in Listing 1:

The main methods defined in the listing 1.TransactionDefinition interface:

public interface transactiondefinition{
int getisolationlevel ();//isolation isolation level
int Getpropagationbehavior ();//propagation propagation Behavior
int gettimeout ();//Timeout Time
boolean isreadonly ();//Read Only
}

Before parsing the first attribute, we need to understand a few concepts dirty read, non repeatable READ and Phantom read:

1. Dirty reads (transaction uncommitted, read ahead): Dirty reading means that when a transaction is accessing data and the data has been modified, and the modification has not yet been submitted to the database, another

Transactions also access this data, and then use this data

2. Non-repeatable reading (inconsistent two readings): refers to reading the same data multiple times within a transaction. When this transaction is not finished, another transaction accesses the same data. Well, in the first

Two read data in a transaction, as a result of the modification of the second transaction, the data read by the first transaction two times may be different. This happens two times within a transaction read

The data is not the same, so it is called a non repeatable read.

3. Phantom reading: a phenomenon that occurs when a transaction is not executed independently, for example, the first transaction modifies the data in a table that involves all the rows of data in the table. Meanwhile, the second

Transactions also modify the data in this table, which is to insert a new row of data into the table. So, it's going to happen later. User Discovery table for the first transaction there are no modified data

OK, it's like a hallucination.


Next we can go into the anatomy of our first attribute: The transaction isolation level . The isolation level refers to the degree of isolation between several concurrent transactions.


Five constants representing isolation levels are defined in the Transactiondefinition interface:

Transactiondefinition.isolation_default: This is the default value that represents the default isolation level for using the underlying database. For most databases, this value is usually

Transactiondefinition.isolation_read_committed.

Transactiondefinition.isolation_read_uncommitted: This isolation level indicates that one transaction can read data that is modified by another transaction but has not yet been committed. This level does not prevent dirty and unreadable reads, so this isolation level is rarely used.

Transactiondefinition.isolation_read_committed: This isolation level indicates that a transaction can only read data that has been committed by another transaction. This level prevents dirty reading, which is also the recommended value in most cases.

Transactiondefinition.isolation_repeatable_read: This isolation level represents a transaction that can repeat a query multiple times throughout the process, and the records returned each time

Are the same. These new records are ignored even if there is new data between multiple queries that satisfies the query. This level prevents dirty reads and cannot be read again.

Transactiondefinition.isolation_serializable: All transactions are executed one at a time, so that there is absolutely no interference between the transactions, that is, the level can prevent dirty

Read, non-repeatable read, and Phantom Reading. However, this will seriously affect the performance of the program. This level is not normally used.

Transactional propagation Behavior

The propagation behavior of a transaction means that if a transaction context already exists before the current transaction is started, there are several options for specifying the execution behavior of a transactional method.


The following constants are included in the transactiondefinition definition to represent propagation behavior:

Transactiondefinition.propagation_required: If there is currently a transaction, join the transaction, or create a new transaction if there is currently no transaction

Transactiondefinition.propagation_requires_new: Creates a new transaction, suspends the current transaction if there is currently a transaction.

Transactiondefinition.propagation_supports: If there is currently a transaction, the transaction is added, and if there are currently no transactions, it continues to run in a non transactional manner.

Transactiondefinition.propagation_not_supported: Run in a non transactional manner and suspend the current transaction if there is currently a transaction.

Transactiondefinition.propagation_never: Run in a non transactional manner, throw an exception if there is a current transaction.

Transactiondefinition.propagation_mandatory: If there is currently a transaction, the transaction is added, and if there is currently no transaction, an exception is thrown.

Transactiondefinition.propagation_nested: If a transaction currently exists, a transaction is created to run as a nested transaction for the current transaction, or if there are currently no transactions

Value is equivalent to transactiondefinition.propagation_required.


It should be noted that the preceding six transactional propagation behaviors are introduced by Spring from the EJB, and they share the same concepts. And propagation_nested is unique to Spring.

Transactions initiated with propagation_nested are embedded in external transactions, if external transactions exist. At this point, the inline transaction is not a separate transaction, it depends on the external transaction

exists, only the submission of external transactions can cause internal transactions to be committed, and nested child transactions cannot be submitted separately. If you are familiar with the concept of a savepoint in JDBC, it is easy to understand the nested transaction.

, the nested child transaction is an application of the savepoint, and a transaction can include multiple savepoint, each nested transaction. In addition, the rollback of external transactions can also cause the back of the nested transaction

Rolling

Transaction Pending

For example: Method A supports transactions, method B does not support transactions, method a invokes method B. When method a begins to run, the system establishes a Transaction for it, method A for the processing of the database

, will be under the control of the transaction. At this point, method A calls method B, the Transaction of method A is suspended, and any database operation in method B is not in the

Under the management of Transaction. When method B returns, method A continues to run, before the Transaction is restored, and the following database operation continues to be committed under the control of the Transaction or back

Rolling.

Transaction timeout

A transaction timeout, which is the maximum time that an office allows to execute, is automatically rolled back if the time limit is exceeded but the transaction is not completed. In transactiondefinition with int

Value to indicate the timeout, in seconds.

Read-only property of transaction

A read-only property of a transaction is a read-only or read-write operation of a transactional resource. If you are certain that only read-only operations are performed on transactional resources, then we can make the transaction flag read-only to

The performance of high transaction processing. A Boolean type in Transactiondefinition to indicate whether the transaction is read-only.

Rollback rules for transactions

Typically, if an unchecked exception (inherited from RuntimeException) is thrown in a transaction, the transaction is rolled back by default, or if no exception is thrown, or if the checked

Exception, the transaction is still committed. This is often the way most developers want to handle it, and it's the default processing in EJBS. However, we can control transactions according to the need to throw some

Commits a transaction when an exception is not checked, or rolls back the transaction when some checked exceptions are thrown.


Platformtransactionmanager

Listing 2. The main methods defined in the Platformtransactionmanager interface:

public interface platformtransactionmanager{
  transactionstatus gettransaction (transactiondefinition definition )
   throws TransactionException;
   void commit (Transactionstatus status) throws TransactionException;
   void rollback (Transactionstatus status) throws TransactionException;
}

Depending on the different persistence APIs or frameworks used at the bottom, the main implementation classes for Platformtransactionmanager are as follows:

1. Datasourcetransactionmanager: Applicable to data persistence operations using JDBC and IBatis.

2. Hibernatetransactionmanager: Applicable to the use of Hibernate for data persistence operations.

3.JpaTransactionManager: Applies to data persistence operations using JPA.

4. There are also Jtatransactionmanager, Jdotransactionmanager, Jmstransactionmanager and others.


If we use JTA for transaction management, we can get a container managed by the JNDI and Spring Jtatransactionmanager

DataSource. Jtatransactionmanager does not need to know DataSource and other specific resources because it will use the global transaction management provided by the container. And for other transaction management

, such as Datasourcetransactionmanager, need to provide the underlying data source as its attribute, or DataSource, when defined. and Hibernatetransactionmanager on

Should be sessionfactory, and jpatransactionmanager corresponding is entitymanagerfactory and so on.


Transactionstatus

Platformtransactionmanager.gettransaction (...) method returns a Transactionstatus object. The returned Transactionstatus object may represent a new or already saved

The transaction in (if there is a qualifying transaction on the current call stack). The Transactionstatus interface provides a simple way to control the state of transaction execution and querying transactions. The interface is set

The righteousness is shown in Listing 3:

Listing 3. The main methods defined in the Transactionstatus interface

Public  Interface transactionstatus{
   boolean isnewtransaction ();
   void Setrollbackonly ();
   Boolean isrollbackonly ();
}

Programmatic Transaction Management

an overview of spring's programmatic transaction management

Prior to spring, programmatic transaction management was the only option for POJO based applications. People who have used Hibernate should know that we need to explicitly call BeginTrans in code

Action (), Commit (), rollback (), and other transaction management-related methods, that is, programmatic transaction management. With the transaction management API provided by Spring, we can control things in code flexibly

The implementation of the service. At the bottom, Spring still delegates transaction operations to the underlying persistence framework for execution.

programming transaction management based on the underlying API

Based on the three core interfaces of Platformtransactionmanager, Transactiondefinition and Transactionstatus, we can manage the transaction in a programmatic way. Shown

The example code is shown in Listing 4 (see my Java Transaction series for specific code):

public class Bankserviceimpl implements Bankservice {
private Bankdao Bankdao;
Private Transactiondefinition txdefinition;
Private Platformtransactionmanager Txmanager;
......
Public boolean transfer (long Fromid, long toid, double amount) {transactionstatus
txstatus = txmanager.gettransacti On (txdefinition);
Boolean result = false;
try {result
= Bankdao.transfer (Fromid, toid, amount);
Txmanager.commit (Txstatus);
} catch (Exception e) {result
= false;
Txmanager.rollback (txstatus);
System.out.println ("Transfer error!");
}
return result;
}

The corresponding configuration file is as follows:

<bean id= "Bankservice" class= "Footmark.spring.core.tx.programmatic.origin.BankServiceImpl" >
< Property Name= "Bankdao" ref= "Bankdao"/> <property name= "Txmanager
" ref= "TransactionManager"/>
<property name= "Txdefinition" >
<bean class= " Org.springframework.transaction.support.DefaultTransactionDefinition ">
<property name=" Propagationbehaviorname "value=" propagation_required "/>
</bean>
</property>
</ Bean>

As shown above, we have added two attributes to the class: one is the Transactiondefinition type property that defines a transaction, and the other is a Platformtransactionmanager type property, with the

To perform transaction management operations. If the method needs to implement transaction management, we first need to start a transaction before the method starts executing, calling the Platformtransactionmanager.gettransactio

N (...) method to start a transaction. Once a transaction has been created and started, you can start writing business logic code and then commit or rollback the transaction where appropriate.

Transactiontemplate-based programmatic transactions

As you can see from the previous example, this transaction management approach is easy to understand, but it is frustrating that the code for transaction management is scattered in business logic code, disrupting the organization of the original code, and

Each business method contains a similar sample code to start a transaction, COMMIT/Rollback a transaction Fortunately, Spring is aware of these problems and provides a simplified approach, which is spring's

The template callback method that is often used by the data DAO layer, as shown in Listing 6:

Listing 6. Transactiontemplate-based transaction management sample code

public class Bankserviceimpl implements Bankservice 
{
	private Bankdao Bankdao;
	Private Transactiontemplate transactiontemplate;
	......
	Public boolean transfer (final long fromid, final long toid, final double amount) 
	{return
		(Boolean) Transactiontem Plate.execute (New Transactioncallback ()
		{public
			Object dointransaction (transactionstatus status) 
			{
				Object result;
				try {result
					= Bankdao.transfer (Fromid, toid, amount);
				} catch (Exception e) {
					status.setrollbackonly (); Result
					= false;
					System.out.println ("Transfer error!");
				}
				return result
			}}
		);}

The corresponding Bean configuration instance is as follows:

Listing 7. Transactiontemplate-based transaction management sample Bean file

<bean id= "Bankservice"
class= "Footmark.spring.core.tx.programmatic.template.BankServiceImpl" >
<property name= "Bankdao" ref= "Bankdao"/> <property name= "Transactiontemplate"
Transactiontemplate "/>
</bean>

Because the system I am developing now is the financial system, the financial system itself is very demanding, not only is it able to control the boundary of the transaction precisely, but its beginning and ending is

The process of handling after an exception has to be under our control (a control freak), so our project chooses this implementation of spring programming transactions.

Declarative Transaction Management

An overview of Spring's declarative transaction management

Spring's declarative transaction management is based on AOP on the ground floor. The essence is to intercept the method before and after, and then create or join a transaction before the target method starts,

Commits or rolls back the transaction based on execution after the target method has been completed. The greatest advantage of declarative transactions is that they do not require programmatic management of transactions so that they do not need to be doped in the business logic code

Transaction management code, you can apply a transaction rule to the business logic by simply making the relevant transaction rule declaration in the configuration file (or through an equivalent annotation-based approach). Because the transaction management itself

is a typical crosscutting logic that is where AOP comes in. The Spring development team is aware of this and provides simple and powerful support for declarative transactions. Compared to programmatic transactions,

The only problem with declarative transactions is that the latter's finest granularity can only function at the method level and cannot be done at the level of code blocks like programmatic transactions. But even with this demand, there are a lot of flexible

Methods, for example, you can separate code blocks that require transaction management into methods, and so on.

Let's take a look at the declarative transaction management capabilities that Spring provides for us.


Transactionproxyfactorybean-based declarative transaction management

Listing 9. Transactionproxyfactorybean-based transaction management sample configuration file

<beans......> ...
	<bean id= "Bankservicetarget"
		class= "Footmark.spring.core.tx.declare.classic.BankServiceImpl" >
		<property name= "Bankdao" ref= "Bankdao"/>
	</bean>
 
	<bean id= "Bankservice" class= "
		Org.springframework.transaction.interceptor.TransactionProxyFactoryBean ">
		<property name=" target "ref= "Bankservicetarget"/>
		<property name= "TransactionManager" ref= "TransactionManager"/>
		< Property name= "Transactionattributes" >
			<props>
				<prop key= "Transfer" >propagation_ REQUIRED </prop>
			</props>
		</property>
	</bean>
... </beans>

Explicitly configuring a Transactionproxyfactorybean for each business class will make the code appear too rigid


Declarative transaction management based on <tx> namespaces

The preceding declarative transaction configuration method lays the cornerstone of Spring declarative transaction management. On this basis, Spring 2.x introduced the <tx> namespace, combined with <aop> namespaces, to bring

The developer configures a new experience of declarative transactions, and the configuration becomes simpler and more flexible. In addition, declarative transactions become more powerful thanks to the tangency-expression support of the <aop> namespace

<beans......> ...
	<bean id= "Bankservice"
		class= "Footmark.spring.core.tx.declare.namespace.BankServiceImpl" >
		< Property Name= "Bankdao" ref= "Bankdao"/>
	</bean>
	<tx:advice id= "Bankadvice" Transaction-manager = "TransactionManager" >
		<tx:attributes>
			<tx:method name= "transfer" propagation= "REQUIRED"/ >
		</tx:attributes>
	</tx:advice>
	<aop:config>
		<aop:pointcut id= " Bankpointcut "expression=" Execution (* *.transfer (..))/> <aop:advisor advice-ref= "
		bankadvice" pointcut-ref= "Bankpointcut"/>
	</aop:config> ...
</beans>

Because the pointcut expression is used, we do not need to create a proxy object for each business class. Also, if the name of the configured transaction manager Bean is evaluated

To "TransactionManager", we can omit the <tx:advice> Transaction-manager property because the default value of the property is "TransactionManager"

@Transactional-based declarative transaction management

In addition to the namespace-based transaction configuration, Spring 2.x introduces a Annotation based approach that mainly involves @Transactional annotations. @Transactional can be used for

Interfaces, interface methods, classes, and class methods. When used on a class, all public methods of that class will have transactional properties of that type, and we can also use the callout at the method level to

Overrides the definition of class level. As shown in Listing 12:

Listing 12. @Transactional-based transaction management sample configuration file

@Transactional (propagation = propagation.required) public
boolean transfer (Long Fromid, long toid, double amount) 
  {return
	bankdao.transfer (Fromid, toid, amount);

Spring uses Beanpostprocessor to process annotations in the bean, so we need to make the following declaration in the configuration file to activate the reprocessing bean, as shown in Listing 13

Listing 13. To process the configuration of a Bean after enabled

<tx:annotation-driven transaction-manager= "TransactionManager"/>

Similar to previous, the default value for the Transaction-manager property is TransactionManager, which can be omitted if the transaction manager Bean's name is that value. Although @Transactional annotations can

Works on interfaces, interface methods, classes, and class methods, but the Spring team does not recommend that annotations be used on interfaces or interface methods, because it is only used when using an interface based proxy

Effect. In addition, @Transactional annotations should be applied only to the public method, which is determined by the nature of Spring AOP. If you are visible in protected, private, or by default

Method of using @Transactional annotation, which is ignored and does not throw any exceptions.

Based on the <tx> namespace and @Transactional-based transaction declarations, each has its advantages and disadvantages. The advantage of a <tx> based approach is that it combines with a tangent point expression and is powerful. Using tangent points to express

, a configuration can match multiple methods, and the @transactional approach must be annotated on every method or class that needs to use the transaction, although most

The rules for counting transactions are consistent, but they cannot be reused for @Transactional, and must be specified individually. On the other hand, it's very simple to use it on a @Transactional basis.

, without the cost of learning. Developers can choose one or the other, depending on their needs, or even mix the two approaches as needed.


If the legacy code is not maintained, the reuse of transactioninterceptor based and Transactionproxyfactorybean declarative transaction management is not recommended, but

Learning these two ways is very conducive to the understanding of the underlying implementation, because the length of too long, I only pick Transactionproxyfactorybean to write.

Leverage Transactionproxyfactorybean to generate transaction agents

<?xml version= "1.0" encoding= "gb2312"?> <!--the header of the Spring configuration file, including information such as DTDs--> DOCTYPE beans Public "-//spring//dtd bean//en" "Http://www.springframework.org/dtd/spring-beans.dtd" > &LT;BEANS&G
    	T <!--define data source--> <bean id= "DataSource" class= "Org.springframework.jdbc.datasource.DriverManagerDataSource" &G
        		T <!--define database driven--> <property name= "Driverclassname" ><value>com.mysql.jdbc.driver</value ></property> <!--define database url--> <property name= "url" ><value>jdbc:mysql ://localhost:3306/spring</value></property> <!--define database user name--> <property name= "user Name ><value>root</value></property> <!--define database password--> <property NA Me= "Password" ><value>32147</value></property> </bean> <!--define a hibernate sess Ionfactory--> <bean id="Sessionfactory" class= "Org.springframework.orm.hibernate3.LocalSessionFactoryBean" > <!--definition sessionfact 
            		Ory must inject datasource--> <property name= "DataSource" ><ref local= "DataSource"/></property> <property name= "Mappingresources" > <list> <!--The following are used to list all the PO Map file--> <value>Person.hbm.xml</value> </list> ;/property> <property name= "Hibernateproperties" > <props> <!--here to define H Ibernate sessionfactory Properties: Different database connections, select Create,update,create-drop--> <prop key= at startup Hibernate.dia Lect ">org.hibernate.dialect.MySQLDialect</prop> <prop key=" Hibernate.hbm2ddl.auto ">update< /prop> </props> </property> </bean> <!--define the transaction manager and use the transaction manager for Hibernte --> <bean id= "TranSactionmanager "class=" Org.springframework.orm.hibernate3.HibernateTransactionManager "> <!-- Hibernatetransactionmanager beans need to rely on injecting a reference to a sessionfactory bean--> <property name= "Sessionfactory" & Gt;<ref local= "Sessionfactory"/></property> </bean> <!--Configure Transaction Interceptor--> <bean id= "transact Ioninterceptor "class=" Org.springframework.transaction.interceptor.TransactionInterceptor "> <!--transaction Interceptor Bea n requires dependency injection of a transaction manager--> <property name= "TransactionManager" ref= "TransactionManager"/> <property N  Ame= "Transactionattributes" > <!--define transaction propagation properties--> <props> <prop key= "insert*" >PROPAGATION_REQUIRED</prop> <prop key= "find*" >propagation_required,readonly& lt;/prop> <prop key= "*" >PROPAGATION_REQUIRED</prop> </props> < /property> </bEan> <!--define Beannameautoproxycreator, the bean is a bean-post processor without reference, so there is no id attribute to this bean post processor, which automatically creates a transaction agent for the target bean based on the transaction interceptor <bean class= "Org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator" > Specify which Bean name to meet The bean automatically generates the business agent-->

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.