Spring (9) Support for transactions by Spring
I. transaction support
Transaction: a unit of work for a group of atomic operations. Either all succeed or all fail.
Spring transaction management method:
- JDBC programming Transaction Management: -- can control the rows in the code
The transaction boundary can be clearly controlled, and the granularity of transaction control is fine (programming method))
- JDBC declarative Transaction Management-controls Methods
Transaction-related APIs do not need to be involved in the program, and the transaction management is decoupled from the actual business code (the XML method is configured)
Ii. JDBC programming Transaction Management
Spring provides two programming-based transaction management methods:
- Implement the PlatformTransactionManager Interface
- Use the TransactionTemplate Mode
2.1,
Implement the PlatformTransactionManager Interface
General steps:
- Implementation class of PlatformTransactionManager
- Define transaction TransactionDefinition
- Send transaction definitions to TransactionStatus
- Use the try. catch statement to seal the transaction to be executed.
- If a transaction error occurs, call the rollback method of PlatformTransactionManager.
Package com. pb. transaction. demo; import javax. SQL. dataSource; import org. springframework. context. support. classPathXmlApplicationContext; import org. springframework. jdbc. core. jdbcTemplate; import org. springframework. transaction. platformTransactionManager; import org. springframework. transaction. transactionStatus; import org. springframework. transaction. support. defaultTransactionDefinition;/*** use TransactionManager Transaction Management * disadvantage: intrusive Code * advantage: fine-grained control */public class TransactionManagerDemo {public static void main (String [] args) {ClassPathXmlApplicationContext cpx = new ClassPathXmlApplicationContext ("applicationContext. xml "); // obtain the platform object PlatformTransactionManager ptm = (PlatformTransactionManager) cpx. getBean ("transactionManager"); // DefaultTransactionDefinition dtd = new DefaultTransactionDefinition (); // sets the behavior dtd of the transaction definer. setPropagationBehavior (DefaultTransactionDefinition. PROPAGATION_REQUIRED); // The transaction status is created using the Transaction Manager. TransactionStatus ts = ptm. getTransaction (dtd); // perform a transaction try {// obtain the data source DataSource ds = (DataSource) cpx. getBean ("dataSource"); // create JDBCTemplacte JdbcTemplate jt = new JdbcTemplate (ds); // execute operations such as update or insert. update ("insert into person values (11, 'ttm ', 23)"); jt. update ("update person set name = 'zhang wangba 'where id = 7"); ptm. commit (ts); System. out. println ("============");} catch (Exception e) {ptm. rollback (ts); System. out. println ("undo ======="); e. printStackTrace ();}}}
2.2,
Use the TransactionTemplate Mode
General steps:
- A TransactionManager needs to be encapsulated.
- Create a transaction rollback class
- Execute () method of TransactionManager
Package com. pb. transaction. demo; import javax. SQL. dataSource; import org. springframework. context. support. classPathXmlApplicationContext; import org. springframework. jdbc. core. jdbcTemplate; import org. springframework. transaction. platformTransactionManager; import org. springframework. transaction. transactionStatus; import org. springframework. transaction. support. defaultTransactionDefinition; import org. springframework. transaction. support. transactionCallback; import org. springframework. transaction. support. transactionCallbackWithoutResult; import org. springframework. transaction. support. transactionTemplate;/*** use TransactionTemplate to manage transactions disadvantages: intrude into code advantages: fine-grained control */public class TransactionTeplateDemo {public static void main (String [] args) {ClassPathXmlApplicationContext cpx = new ClassPathXmlApplicationContext ("applicationContext. xml "); // obtain the platform object PlatformTransactionManager ptm = (PlatformTransactionManager) cpx. getBean ("transactionManager"); // transaction template TransactionTemplate tt = new TransactionTemplate (ptm); // obtain the data source DataSource ds = (DataSource) cpx. getBean ("dataSource"); // create JDBCTemplacte final JdbcTemplate jt = new JdbcTemplate (ds); // implement the transaction callback function tt.exe cute (new TransactionCallbackWithoutResult () {@ Override protected void doInTransactionWithoutResult (TransactionStatus arg0) {// execute operations such as update or insert. jt. update ("insert into person values (17, 'Tom ', 23)"); jt. update ("update person set name = 'Li Si 3 'where id = 4 ");}});}}
2.3 programming transaction Configuration
<? 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: p = "http://www.springframework.org/schema/p" xsi: schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> <! -- Declare the data source org. springframework. jdbc. datasource. driverManagerDataSource/com. mchange. v2.c3p0. comboPooledDataSource --> <bean id = "dataSource" class = "org. apache. commons. dbcp. basicDataSource "destroy-method =" close "> <! -- Driver --> <property name = "driverClassName" value = "oracle. jdbc. driver. OracleDriver"/> <! -- Url --> <property name = "url" value = "jdbc: oracle: thin: @ localhost: 1521: orcl"/> <! -- Username --> <property name = "username" value = "accp"/> <! -- Password --> <property name = "password" value = "accp"/> </bean> <bean id = "transactionManager" class = "org. springframework. jdbc. datasource. dataSourceTransactionManager "> <property name =" dataSource "ref =" dataSource "> </property> </bean> </beans>
Iii. JDBC declarative Transaction Management
Mainly implemented through the AOP Function
You do not need to modify the original class.
Use TransationProxyFactoryBean to specify the transaction to be involved and the Method
Entity class: There are tables corresponding to the database
package com.pb.entity;public class Person { private Long id; private String name; private Integer age; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
Dao and implementation class
Package com. pb. dao; import java. util. list; import com. pb. entity. person; public interface PersonDao {public int insert (Person p); public int batchInsert (List <Person> persons);} // implements class package com. pb. dao. impl; import java. util. list; import javax. SQL. dataSource; import org. springframework. jdbc. core. jdbcTemplate; import com. pb. dao. personDao; import com. pb. entity. person; public class PersonDaoImpl implements Pers OnDao {private JdbcTemplate jdbcTemplate; public void setDataSource (DataSource ds) {jdbcTemplate = new JdbcTemplate (ds) ;}@ Override public int insert (Person p) {String SQL = "insert into person values (?,?,?) "; Object [] params = {p. getId (), p. getName (), p. getAge ()}; return jdbcTemplate. update (SQL, params) ;}@ Override public int batchInsert (List <Person> persons) {int count = 0; for (Person person: persons) {insert (person ); count ++;} return count ;}}
Test class
Package com. pb. transation. aop. demo; import java. util. arrayList; import java. util. list; import org. springframework. context. support. classPathXmlApplicationContext; import com. pb. dao. personDao; import com. pb. entity. person; public class FirstAOPTransationDemo {public static void main (String [] args) {ClassPathXmlApplicationContext cpx = new ClassPathXmlApplicationContext ("applicationContext. xml "); // The proxy class PersonDao personDao = (PersonDao) cpx. getBean ("personDaoProxy"); Person p1 = new Person (); p1.setId (new Long (28); p1.setName ("zhuque"); p1.setAge (199 ); person p2 = new Person (); p2.setId (new Long (29); p2.setName (""); p2.setAge (150 ); list <Person> persons = new ArrayList <Person> (); persons. add (p1); persons. add (p2); int count = personDao. batchInsert (persons); System. out. println ("updated," + count + "record ");}}
ApplicationContext. xml 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: p = "http://www.springframework.org/schema/p" xsi: schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> <! -- Declare the data source org. springframework. jdbc. datasource. driverManagerDataSource/com. mchange. v2.c3p0. comboPooledDataSource --> <bean id = "dataSource" class = "org. apache. commons. dbcp. basicDataSource "destroy-method =" close "> <! -- Driver --> <property name = "driverClassName" value = "oracle. jdbc. driver. OracleDriver"/> <! -- Url --> <property name = "url" value = "jdbc: oracle: thin: @ localhost: 1521: orcl"/> <! -- Username --> <property name = "username" value = "accp"/> <! -- Password --> <property name = "password" value = "accp"/> </bean> <! -- Interface implementation class --> <bean id = "personDao" class = "com. pb. dao. impl. personDaoImpl "> <property name =" dataSource "ref =" dataSource "> </property> </bean> <bean id =" transactionManager "class =" org. springframework. jdbc. datasource. dataSourceTransactionManager "> <property name =" dataSource "ref =" dataSource "> </property> </bean> <bean id =" personDaoProxy "class =" org. springframework. transaction. interceptor. transactionProxyFactoryBe An "> <! -- Specify the interface --> <property name = "proxyInterfaces"> <list> <value> com. pb. dao. PersonDao </value> </list> </property> <! -- Management target --> <property name = "target" ref = "personDao"/> <! -- Inject Transaction Management --> <property name = "transactionManager" ref = "transactionManager"> </property> <! -- Transaction management methods and methods --> <property name = "transactionAttributes"> <props> <prop key = "batch *"> PROPAGATION_REQUIRED </prop> </props> </ property> </bean> </beans>
Iv. Transaction attributes
Declarative transactions use methods as boundaries. In short, a method is considered as a transaction.
Attributes of transactions in Spring:
- Propagation Behavior)
- Isolation Level)
- Read-only prompt (Rean-only Hints)
- Transaction Timeout period (The Transaction Timeout period)
4.1 Propagation Behavior
4.2 isolation level
V. Declarative Transaction Management after Spring2.0: Based on XMLSchema
Steps:
<? 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: p = "http://www.springframework.org/schema/p" xmlns: aop = "http://www.springframework.org/schema/aop" xmlns: tx = "http://www.springframework.org/schema/tx" xsi: schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd htt P: // www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd "> <! -- Declare the data source org. springframework. jdbc. datasource. driverManagerDataSource/com. mchange. v2.c3p0. comboPooledDataSource --> <bean id = "dataSource" class = "org. apache. commons. dbcp. basicDataSource "destroy-method =" close "> <! -- Driver --> <property name = "driverClassName" value = "oracle. jdbc. driver. OracleDriver"/> <! -- Url --> <property name = "url" value = "jdbc: oracle: thin: @ localhost: 1521: orcl"/> <! -- Username --> <property name = "username" value = "accp"/> <! -- Password --> <property name = "password" value = "accp"/> </bean> <! -- Interface implementation class --> <bean id = "personDao" class = "com. pb. dao. impl. personDaoImpl "> <property name =" dataSource "ref =" dataSource "> </property> </bean> <! -- Transaction management class --> <bean id = "transactionManager" class = "org. springframework. jdbc. datasource. dataSourceTransactionManager "> <property name =" dataSource "ref =" dataSource "> </property> </bean> <! -- Specify transaction Management --> <tx: advice id = "txAdvice" transaction-manager = "transactionManager"> <! -- Specify methods and methods --> <tx: attributes> <tx: method name = "batch *" propagation = "REQUIRED"/> </tx: attributes> </tx: advice> <aop: config> <! -- Entry point --> <aop: pointcut expression = "execution (* com. pb. dao. PersonDao. * (..)" id = "mypoint"/> <! -- Close the start point and cut in the Object Transaction --> <aop: advisor advice-ref = "txAdvice" pointcut-ref = "mypoint"/> </aop: config> </beans>
6. annotation-based transaction management
Package com. pb. dao. impl; import java. util. list; import javax. SQL. dataSource; import org. springframework. jdbc. core. jdbcTemplate; import org. springframework. transaction. annotation. propagation; import org. springframework. transaction. annotation. transactional; import com. pb. dao. personDao; import com. pb. entity. person; // Add @ transactional @ Transactionalpublic class PersonDaoImpl implements PersonDao {privat under the class to be managed E JdbcTemplate jdbcTemplate; public void setDataSource (DataSource ds) {jdbcTemplate = new JdbcTemplate (ds) ;}@ Override public int insert (Person p) {String SQL = "insert into person values (?,?,?) "; Object [] params = {p. getId (), p. getName (), p. getAge ()}; return jdbcTemplate. update (SQL, params);} // Add the property propagation = Propagation under the method to be managed. REQUIRED @ Transactional (propagation = Propagation. REQUIRED) public int batchInsert (List <Person> persons) {int count = 0; for (Person person: persons) {insert (person); count ++ ;} return count ;}}
Add
<? 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: p = "http://www.springframework.org/schema/p" xmlns: aop = "http://www.springframework.org/schema/aop" xmlns: tx = "http://www.springframework.org/schema/tx" xsi: schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd htt P: // www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd "> <! -- Declare the data source org. springframework. jdbc. datasource. driverManagerDataSource/com. mchange. v2.c3p0. comboPooledDataSource --> <bean id = "dataSource" class = "org. apache. commons. dbcp. basicDataSource "destroy-method =" close "> <! -- Driver --> <property name = "driverClassName" value = "oracle. jdbc. driver. OracleDriver"/> <! -- Url --> <property name = "url" value = "jdbc: oracle: thin: @ localhost: 1521: orcl"/> <! -- Username --> <property name = "username" value = "accp"/> <! -- Password --> <property name = "password" value = "accp"/> </bean> <! -- Interface implementation class --> <bean id = "personDao" class = "com. pb. dao. impl. personDaoImpl "> <property name =" dataSource "ref =" dataSource "> </property> </bean> <! -- Transaction management class --> <bean id = "transactionManager" class = "org. springframework. jdbc. datasource. dataSourceTransactionManager "> <property name =" dataSource "ref =" dataSource "> </property> </bean> <! -- Specify the transaction manager in annotation mode --> <tx: annotation-driven transaction-manager = "transactionManager"/> </beans>