Spring entry (3) [transaction control], spring entry transaction control
The database needs to be operated during development, and the process of adding, deleting, and modifying operations is one operation. If you need to update multiple tables in a business, the update of any table fails, update of the entire business is a failure. In this case, tables that have been successfully updated must be rolled back. Otherwise, an error occurs in the business and a transaction is required. That is, the operation of this business is a transaction, transactions are atomic, isolated, consistent, and persistent. At this time, transactions are used. The purpose of transaction control is to ensure that a group of operations either succeed or fail. Spring provides support for transactions. In spring, there are two main ways to use transactions: 1. Programmatic transaction control; 2. Declarative transaction control.
I. Programmatic transaction control
The so-called programmatic transaction control implements transaction control by writing code.
Spring provides a Transaction Manager to facilitate transaction processing. In the final result, the transaction manager is used to control the transaction. All the transaction control in spring must have a Transaction Manager. The following is an example of a programmatic transaction control that transfers funds between accounts. We place the transaction control on the service layer of the system (including the controller layer, service layer, and DAO Layer) the following is my spring configuration file,
<? Xml version = "1.0" encoding = "UTF-8"?> <Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns: aop = "http://www.springframework.org/schema/aop" xmlns: tx = "http://www.springframework.org/schema/tx" xmlns: context = "http://www.springframework.org/schema/context" xsi: schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0. Xsdhttp: // www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd "> <! -- Spring Automatic Detection --> <context: component-scan base-package = "com.cn. study. day5"/> <! ----> <Context: property-placeholder location = "classpath: db. properties"/> <! ----> <Bean id = "dataSource" class = "org. springframework. jdbc. datasource. driverManagerDataSource "> <property name =" driverClassName "> <value >$ {db. driver} </value> </property> <property name = "url"> <value >$ {db. url} </value> </property> <property name = "username"> <value >$ {db. username} </value> </property> <property name = "password"> <value> 123456 </value> </property> </bean> <bean id = "dao "class =" com.cn. study. day5.service. Inter. impl. AccountDaoImpl "> <property name =" dataSource "ref =" dataSource "> </property> </bean> <! -- Configure the Transaction Manager --> <bean id = "transactionManager" class = "org. springframework. jdbc. datasource. dataSourceTransactionManager "> <property name =" dataSource "ref =" dataSource "> </property> </bean> <! -- Transaction Manager template facilitates the use of transactions --> <bean id = "transactionTemplate" class = "org. springframework. transaction. support. transactionTemplate "> <property name =" transactionManager "ref =" transactionManager "> </property> </bean> </beans>
The transaction manager is configured. cetcetransactionmanager is used here. The dataSource attribute of the transaction manager must be configured. Here, the ref attribute is used to reference the preceding one. With the Transaction Manager, it is still difficult to use transactions. spring also provides the Transaction Manager template. We configure the Transaction Manager template. The transaction manager template requires a Transaction Manager attribute, we reference the above Transaction Manager. So far, the configuration file for the programmatic transaction control has been prepared, and the following is a programmatic development. Because we put the transaction control at the service layer, below is the code of my service layer,
Package com.cn. study. day5.service. inter. impl; import org. springframework. beans. factory. annotation. autowired; import org. springframework. stereotype. component; import org. springframework. transaction. transactionStatus; import org. springframework. transaction. support. transactionCallback; import org. springframework. transaction. support. transactionCallbackWithoutResult; import org. springframework. transaction. support. transactionTemplate; import com.cn. study. day5.service. inter. accountDaoInter; import com.cn. study. day5.service. inter. accountServiceIter; @ Componentpublic class AccountServiceImpl implements AccountServiceIter {@ Autowired private AccountDaoInter adi; @ Autowired private TransactionTemplate tt; // transfer method, convert from out to in: money RMB @ Override public void transfer (final String out, final String in, final double money) {// TODO Auto-generated method stub // use the Transaction Manager template for transaction control tt.exe cute (new TransactionCallbackWithoutResult () {@ Override protected void doInTransactionWithoutResult (TransactionStatus status) {// TODO Auto-generated method stub adi. outMoney (out, money); // an exception that uses transaction control. When an exception occurs, the transaction rolls back int I = 1/0; adi. inMoney (in, money );}});}}
Because it is interface-oriented programming, here I only paste the implementation of the service layer, using the automatic scanning mechanism (scanning class, attribute annotation @ Component, @ Autowired ), the transfer method is used to transfer funds. First, transfer funds from one account to another. Use the execute method in the Transaction Manager template to create a TransactionCallBack instance, here, the anonymous internal class is used to put the method to be executed in doInTransactionWithoutResult for execution, ensuring transaction control.
This method can ensure transaction control. However, in the actual development process, this method changes the code too much and does not comply with the low intrusion development principle. This method is rarely used in development, the most commonly used is declarative transaction control.
Ii. Declarative transaction control
Declarative transaction control is divided into three methods: 1. Declarative Transaction Control Based on TransactionProxyFactoryBean proxy; 2. Declarative transaction control using AOP; iii. Declarative Transaction Control Based on @ Transactional annotation.
1. Declarative Transaction Control Based on TransactionProxyFactoryBean
TransactionProxyFactoryBean is the transaction proxy class. spring will generate a proxy for the target class. The specific configuration is as follows,
<! -- Configure the Transaction Manager --> <bean id = "transactionManager" class = "org. springframework. jdbc. datasource. dataSourceTransactionManager "> <property name =" dataSource "ref =" dataSource "> </property> </bean> <! -- Configure the service layer proxy --> <bean id = "accountServiceProxy" class = "org. springframework. transaction. interceptor. transactionProxyFactoryBean "> <property name =" target "ref =" accountServiceImpl "> </property> <property name =" transactionManager "ref =" transactionManager "> </property> <property name = "transactionAttributes"> <props> <prop key = "transfer"> </prop> </props> </property> </bean>
Only the configuration of the Transaction Manager and the business layer proxy is pasted here. The configuration of the remaining data source and business class can be executed. As mentioned above, no matter which method is used to configure transaction management, you must use the Transaction Manager. Focus on the business layer proxy. The class attribute configured is TransactionProxyFactoryBean. Three attributes need to be configured: target (specific business layer implementation class to be proxy), transactionManager (Transaction Manager), transactionAttributes (the business layer method to intercept ). After the configuration is complete, you can perform a test. The test code is as follows,
ApplicationContext ac=getApplicationContext(); AccountServiceIter asi=(AccountServiceIter)ac.getBean("accountServiceProxy"); asi.transfer("aa", "cc", 10d);
The getApplicationContext () method is used to obtain the ApplicationContext instance and the accountServiceProxy instance. The obtained instance is not the AccountServiceImpl instance but the proxy instance object. Because the proxy is used, the actual service class is proxy, the actual class cannot be used here, but the proxy class should be used.
To use this method, you need to configure a proxy for each business class that requires transactions, so this method is almost unnecessary during development.
2. Declarative transaction control using AOP
This method is used in the development process. The configuration is as follows,
<! -- Configure the Transaction Manager --> <bean id = "transactionManager" class = "org. springframework. jdbc. datasource. dataSourceTransactionManager "> <property name =" dataSource "ref =" dataSource "> </property> </bean> <! -- Configure transaction enhancement --> <tx: advice id = "advicer" transaction-manager = "transactionManager"> <tx: attributes> <tx: method name = "transfer *" propagation = "REQUIRED"/> </tx: attributes> </tx: advice> <! -- Configure the cut point and transaction notification --> <aop: config> <aop: pointcut id = "myPointcut" expression = "execution (* com.cn. study. day555.service. inter. impl. *. *(..)) "/> <aop: advisor advice-ref =" advicer "pointcut-ref =" myPointcut "/> </aop: config>
Configure the transaction enhancement <tx: advice> to configure the Propagation Behavior of the transaction for the method to be enhanced, and configure the transaction notification for the switch point and the corresponding transaction notification, in this way, the declarative transaction control of AOP is completed.
3. annotation Based on @ Transactional
To use the @ Transactional annotation, You need to enable scanning for this annotation in the configuration file: <tx: annotation-driven transaction-manager = "transactionManager"/>, referencing the transaction manager, then you can use the @ Transactional annotation. This annotation can be used on the class, or on the method. It works on all methods of this class, the method indicates that it takes effect for a single method. You can also configure some attributes and describe them in another article.
Through the description of the above four transaction configuration methods, the second method in the declarative method is more common, less intrusive to the Code, and the third is simple configuration, it is also commonly used, but you need to add @ Transcational annotations to the business class or method to intrude the code.
If any error exists, thank you!