(五)Spring 对事务的支持
第一节:事务简介
满足一下四个条件:
第一:原子性;
第二:一致性;
第三:隔离性;
第四:持久性;
-------------------------------------------------
首先我们认识一下我们为什么需要支持事务,我们事务管理的支持我们的程序会出现什么问题。
例子:
创建数据库:
CREATE TABLE `t_count` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userId` int(11) DEFAULT NULL,
`userName` varchar(20) COLLATE utf8_bin DEFAULT NULL,
`count` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
数据库数据:
T.java:
1 package com.wishwzp.test; 2 3 import org.junit.Before; 4 import org.junit.Test; 5 import org.springframework.context.ApplicationContext; 6 import org.springframework.context.support.ClassPathXmlApplicationContext; 7 8 import com.wishwzp.service.BankService; 9 10 public class T { 11 12 private ApplicationContext ac; 13 14 @Before 15 public void setUp() throws Exception { 16 ac=new ClassPathXmlApplicationContext("beans.xml"); 17 } 18 19 @Test 20 public void transferAccounts() { 21 BankService bankService=(BankService)ac.getBean("bankService"); 22 //userId1向userId2转账了50元 23 bankService.transferAccounts(50, 1, 2); 24 } 25 26 }
beans.xml:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans 7 http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/aop 9 http://www.springframework.org/schema/aop/spring-aop.xsd 10 http://www.springframework.org/schema/context 11 http://www.springframework.org/schema/context/spring-context.xsd"> 12 13 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 14 <property name="driverClassName" value="${jdbc.driverClassName}"/> 15 <property name="url" value="${jdbc.url}"/> 16 <property name="username" value="${jdbc.username}"/> 17 <property name="password" value="${jdbc.password}"/> 18 </bean> 19 20 <context:property-placeholder location="jdbc.properties"/> 21 22 <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"> 23 <constructor-arg ref="dataSource"></constructor-arg> 24 </bean> 25 26 27 <bean id="bankDao" class="com.wishwzp.dao.impl.BankDaoImpl"> 28 <property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"></property> 29 </bean> 30 31 <bean id="bankService" class="com.wishwzp.service.impl.BankServiceImpl"> 32 <property name="bankDao" ref="bankDao"></property> 33 </bean> 34 35 </beans>
jdbc.properties:
1 jdbc.driverClassName=com.mysql.jdbc.Driver 2 jdbc.url=jdbc:mysql://localhost:3306/db_bank?characterEncoding=utf-8 3 jdbc.username=root 4 jdbc.password=root
BankServiceImpl.java:
1 package com.wishwzp.service.impl; 2 3 import com.wishwzp.dao.BankDao; 4 import com.wishwzp.service.BankService; 5 6 public class BankServiceImpl implements BankService{ 7 8 private BankDao bankDao; 9 10 public void setBankDao(BankDao bankDao) { 11 this.bankDao = bankDao; 12 } 13 14 @Override 15 public void transferAccounts(final int count, final int userIdA, final int userIdB) { 16 17 bankDao.outMoney(count, userIdA); 18 bankDao.inMoney(count, userIdB); 19 } 20 }
BankService.java:
1 package com.wishwzp.service; 2 3 public interface BankService { 4 5 /** 6 * A向B转账count元 7 * @param count 8 * @param userIdA 9 * @param userIdB 10 */ 11 public void transferAccounts(int count,int userIdA,int userIdB); 12 }
BankDaoImpl.java:
1 package com.wishwzp.dao.impl; 2 3 import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; 4 import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; 5 6 import com.wishwzp.dao.BankDao; 7 8 public class BankDaoImpl implements BankDao{ 9 10 private NamedParameterJdbcTemplate namedParameterJdbcTemplate; 11 12 13 public void setNamedParameterJdbcTemplate( 14 NamedParameterJdbcTemplate namedParameterJdbcTemplate) { 15 this.namedParameterJdbcTemplate = namedParameterJdbcTemplate; 16 } 17 18 @Override 19 public void inMoney(int money, int userId) { 20 // TODO Auto-generated method stub 21 String sql="update t_count set count=count+:money where userId=:userId"; 22 MapSqlParameterSource sps=new MapSqlParameterSource(); 23 sps.addValue("money", money); 24 sps.addValue("userId", userId); 25 namedParameterJdbcTemplate.update(sql,sps); 26 } 27 28 @Override 29 public void outMoney(int money, int userId) { 30 // TODO Auto-generated method stub 31 String sql="update t_count set count=count-:money where userId=:userId"; 32 MapSqlParameterSource sps=new MapSqlParameterSource(); 33 sps.addValue("money", money); 34 sps.addValue("userId", userId); 35 namedParameterJdbcTemplate.update(sql,sps); 36 } 37 38 }
BankDao.java:
1 package com.wishwzp.dao; 2 3 public interface BankDao { 4 5 public void inMoney(int money,int userId); 6 7 public void outMoney(int money,int userId); 8 }
运行结果显示:
数据库中我们看到,我们的转账成功了。但是如果我们的程序中途出现了异常或者错误问题的话,那就不是这个样子的了。
例子:
将BankDaoImpl.java中的public void inMoney(int money, int userId) {}中的sql语句改成String sql="update t_count2 set count=count+:money where userId=:userId";其实根本就是没有t_count2这个表,所以程序就会出现问题,但是我们运行结果是这个样子的:
这时候我们发现张三的钱转给了李四,但是由于程序的出现问题,李四并没有收到这部分钱。。。。这时候麻烦就大了
(这个时候我们就需要引入事物管理这个概念,将没有成功转账这个功能,事物滚回到之前的状态)
第二节:编程式事务管理
jdbc事务管理器:org.springframework.jdbc.datasource.DataSourceTransactionManager
Spring 提供的事务模版类:org.springframework.transaction.support.TransactionTemplate
-------------
我们在beans.xml文件中配置jdbc事物管理将数据源引入,并且配置Spring 提供的事务,在服务中配置property配置Spring 提供的事务
T.java:
1 package com.wishwzp.test; 2 3 import org.junit.Before; 4 import org.junit.Test; 5 import org.springframework.context.ApplicationContext; 6 import org.springframework.context.support.ClassPathXmlApplicationContext; 7 8 import com.wishwzp.service.BankService; 9 10 public class T { 11 12 private ApplicationContext ac; 13 14 @Before 15 public void setUp() throws Exception { 16 ac=new ClassPathXmlApplicationContext("beans.xml"); 17 } 18 19 @Test 20 public void transferAccounts() { 21 BankService bankService=(BankService)ac.getBean("bankService"); 22 //userId1向userId2转账了50元 23 bankService.transferAccounts(50, 1, 2); 24 } 25 26 }
beans.xml:
1 package com.wishwzp.test; 2 3 import org.junit.Before; 4 import org.junit.Test; 5 import org.springframework.context.ApplicationContext; 6 import org.springframework.context.support.ClassPathXmlApplicationContext; 7 8 import com.wishwzp.service.BankService; 9 10 public class T { 11 12 private ApplicationContext ac; 13 14 @Before 15 public void setUp() throws Exception { 16 ac=new ClassPathXmlApplicationContext("beans.xml"); 17 } 18 19 @Test 20 public void transferAccounts() { 21 BankService bankService=(BankService)ac.getBean("bankService"); 22 //userId1向userId2转账了50元 23 bankService.transferAccounts(50, 1, 2); 24 } 25 26 }
jdbc.properties:
1 jdbc.driverClassName=com.mysql.jdbc.Driver 2 jdbc.url=jdbc:mysql://localhost:3306/db_bank?characterEncoding=utf-8 3 jdbc.username=root 4 jdbc.password=root
BankServiceImpl.java:
1 package com.wishwzp.service.impl; 2 3 import org.springframework.transaction.TransactionStatus; 4 import org.springframework.transaction.support.TransactionCallbackWithoutResult; 5 import org.springframework.transaction.support.TransactionTemplate; 6 7 import com.wishwzp.dao.BankDao; 8 import com.wishwzp.service.BankService; 9 10 public class BankServiceImpl implements BankService{ 11 12 private BankDao bankDao; 13 14 private TransactionTemplate transactionTemplate; 15 16 public void setBankDao(BankDao bankDao) { 17 this.bankDao = bankDao; 18 } 19 20 public void setTransactionTemplate(TransactionTemplate transactionTemplate) { 21 this.transactionTemplate = transactionTemplate; 22 } 23 24 @Override 25 public void transferAccounts(final int count, final int userIdA, final int userIdB) { 26 27 transactionTemplate.execute(new TransactionCallbackWithoutResult() { 28 29 @Override 30 protected void doInTransactionWithoutResult(TransactionStatus status) { 31 // TODO Auto-generated method stub 32 bankDao.outMoney(count, userIdA); 33 bankDao.inMoney(count, userIdB); 34 } 35 }); 36 } 37 }
BankService.java:
1 package com.wishwzp.service; 2 3 public interface BankService { 4 5 /** 6 * A向B转账count元 7 * @param count 8 * @param userIdA 9 * @param userIdB 10 */ 11 public void transferAccounts(int count,int userIdA,int userIdB); 12 }
BankDaoImpl.java:
1 package com.wishwzp.dao.impl; 2 3 import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; 4 import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; 5 6 import com.wishwzp.dao.BankDao; 7 8 public class BankDaoImpl implements BankDao{ 9 10 private NamedParameterJdbcTemplate namedParameterJdbcTemplate; 11 12 13 public void setNamedParameterJdbcTemplate( 14 NamedParameterJdbcTemplate namedParameterJdbcTemplate) { 15 this.namedParameterJdbcTemplate = namedParameterJdbcTemplate; 16 } 17 18 @Override 19 public void inMoney(int money, int userId) { 20 // TODO Auto-generated method stub 21 String sql="update t_count2 set count=count+:money where userId=:userId"; 22 MapSqlParameterSource sps=new MapSqlParameterSource(); 23 sps.addValue("money", money); 24 sps.addValue("userId", userId); 25 namedParameterJdbcTemplate.update(sql,sps); 26 } 27 28 @Override 29 public void outMoney(int money, int userId) { 30 // TODO Auto-generated method stub 31 String sql="update t_count set count=count-:money where userId=:userId"; 32 MapSqlParameterSource sps=new MapSqlParameterSource(); 33 sps.addValue("money", money); 34 sps.addValue("userId", userId); 35 namedParameterJdbcTemplate.update(sql,sps); 36 } 37 38 }
BankDao.java:
1 package com.wishwzp.dao; 2 3 public interface BankDao { 4 5 public void inMoney(int money,int userId); 6 7 public void outMoney(int money,int userId); 8 }
运行结果显示:
这时候我们发现张三的钱转给了李四,但是由于程序的出现问题,李四并没有收到这部分钱。。。。这时候麻烦就大了---------但是我们使用了编程式事务管理,这笔钱被事务滚回了。
虽然程序出现了问题,但是我们的赚钱也停止了,并没有任何损失。这就是使用事务的优点
但是编程式事务管理也有也大的缺点,就是编程式事务管理侵入到业务逻辑代码中了。这并不是我们想要的。。。。
所以我们一般使用的声明式事务管理。。。。。。。。。。。
第三节:声明式事务管理
声明式事务管理分两种:
1,使用XML 配置声明式事务;
2,使用注解配置声明式事务;
1,使用XML 配置声明式事务;
T.java:
1 package com.wishwzp.test; 2 3 import org.junit.Before; 4 import org.junit.Test; 5 import org.springframework.context.ApplicationContext; 6 import org.springframework.context.support.ClassPathXmlApplicationContext; 7 8 import com.wishwzp.service.BankService; 9 10 11 public class T { 12 13 private ApplicationContext ac; 14 15 @Before 16 public void setUp() throws Exception { 17 ac=new ClassPathXmlApplicationContext("beans.xml"); 18 } 19 20 @Test 21 public void transferAccounts() { 22 BankService bankService=(BankService)ac.getBean("bankService"); 23 bankService.transferAccounts(50, 1, 2); 24 } 25 26 }
beans.xml:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xmlns:tx="http://www.springframework.org/schema/tx" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans.xsd 9 http://www.springframework.org/schema/aop 10 http://www.springframework.org/schema/aop/spring-aop.xsd 11 http://www.springframework.org/schema/tx 12 http://www.springframework.org/schema/tx/spring-tx.xsd 13 http://www.springframework.org/schema/context 14 http://www.springframework.org/schema/context/spring-context.xsd"> 15 16 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 17 <property name="driverClassName" value="${jdbc.driverClassName}"/> 18 <property name="url" value="${jdbc.url}"/> 19 <property name="username" value="${jdbc.username}"/> 20 <property name="password" value="${jdbc.password}"/> 21 </bean> 22 23 <!-- jdbc事务管理器 --> 24 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 25 <property name="dataSource" ref="dataSource"></property> 26 </bean> 27 28 <!-- 配置事务通知 --> 29 <tx:advice id="txAdvice" transaction-manager="transactionManager"> 30 <tx:attributes> 31 <tx:method name="*"/> 32 </tx:attributes> 33 </tx:advice> 34 35 <!-- 配置事务切面 --> 36 <aop:config> 37 <!-- 配置切点 --> 38 <aop:pointcut id="serviceMethod" expression="execution(* com.wishwzp.service.*.*(..))" /> 39 <!-- 配置事务通知 --> 40 <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/> 41 </aop:config> 42 43 44 <context:property-placeholder location="jdbc.properties"/> 45 46 <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"> 47 <constructor-arg ref="dataSource"></constructor-arg> 48 </bean> 49 50 51 <bean id="bankDao" class="com.wishwzp.dao.impl.BankDaoImpl"> 52 <property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"></property> 53 </bean> 54 55 <bean id="bankService" class="com.wishwzp.service.impl.BankServiceImpl"> 56 <property name="bankDao" ref="bankDao"></property> 57 </bean> 58 59 </beans>
jdbc.properties:
1 jdbc.driverClassName=com.mysql.jdbc.Driver 2 jdbc.url=jdbc:mysql://localhost:3306/db_bank?characterEncoding=utf-8 3 jdbc.username=root 4 jdbc.password=123456
BankServiceImpl.java:
1 package com.wishwzp.service.impl; 2 3 4 import com.wishwzp.dao.BankDao; 5 import com.wishwzp.service.BankService; 6 7 8 public class BankServiceImpl implements BankService{ 9 10 private BankDao bankDao; 11 12 public void setBankDao(BankDao bankDao) { 13 this.bankDao = bankDao; 14 } 15 16 17 @Override 18 public void transferAccounts(int count, int userIdA, int userIdB) { 19 // TODO Auto-generated method stub 20 // TODO Auto-generated method stub 21 bankDao.outMoney(count, userIdA); 22 bankDao.inMoney(count, userIdB); 23 } 24 25 }
BankService.java:
1 package com.wishwzp.service; 2 3 public interface BankService { 4 5 /** 6 * A向B转账count元 7 * @param count 8 * @param userIdA 9 * @param userIdB 10 */ 11 public void transferAccounts(int count,int userIdA,int userIdB); 12 }
BankDaoImpl.java:
1 package com.wishwzp.dao.impl; 2 3 import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; 4 import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; 5 6 import com.wishwzp.dao.BankDao; 7 8 public class BankDaoImpl implements BankDao{ 9 10 private NamedParameterJdbcTemplate namedParameterJdbcTemplate; 11 12 13 public void setNamedParameterJdbcTemplate( 14 NamedParameterJdbcTemplate namedParameterJdbcTemplate) { 15 this.namedParameterJdbcTemplate = namedParameterJdbcTemplate; 16 } 17 18 @Override 19 public void inMoney(int money, int userId) { 20 // TODO Auto-generated method stub 21 String sql="update t_count2 set count=count+:money where userId=:userId"; 22 MapSqlParameterSource sps=new MapSqlParameterSource(); 23 sps.addValue("money", money); 24 sps.addValue("userId", userId); 25 namedParameterJdbcTemplate.update(sql,sps); 26 } 27 28 @Override 29 public void outMoney(int money, int userId) { 30 // TODO Auto-generated method stub 31 String sql="update t_count set count=count-:money where userId=:userId"; 32 MapSqlParameterSource sps=new MapSqlParameterSource(); 33 sps.addValue("money", money); 34 sps.addValue("userId", userId); 35 namedParameterJdbcTemplate.update(sql,sps); 36 } 37 38 }
BankDao.java:
1 package com.wishwzp.dao; 2 3 public interface BankDao { 4 5 public void inMoney(int money,int userId); 6 7 public void outMoney(int money,int userId); 8 }
运行结果显示:
这时候我们发现张三的钱转给了李四,但是由于程序的出现问题,李四并没有收到这部分钱。。。。这时候麻烦就大了---------但是我们使用了声明式事务管理,这笔钱被事务滚回了。
2,使用注解配置声明式事务;
T.java:
1 package com.wishwzp.test; 2 3 import org.junit.Before; 4 import org.junit.Test; 5 import org.springframework.context.ApplicationContext; 6 import org.springframework.context.support.ClassPathXmlApplicationContext; 7 8 import com.wishwzp.service.BankService; 9 10 11 public class T { 12 13 private ApplicationContext ac; 14 15 @Before 16 public void setUp() throws Exception { 17 ac=new ClassPathXmlApplicationContext("beans.xml"); 18 } 19 20 @Test 21 public void transferAccounts() { 22 BankService bankService=(BankService)ac.getBean("bankService"); 23 bankService.transferAccounts(50, 1, 2); 24 } 25 26 27 28 }
beans.xml:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xmlns:tx="http://www.springframework.org/schema/tx" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans.xsd 9 http://www.springframework.org/schema/aop 10 http://www.springframework.org/schema/aop/spring-aop.xsd 11 http://www.springframework.org/schema/tx 12 http://www.springframework.org/schema/tx/spring-tx.xsd 13 http://www.springframework.org/schema/context 14 http://www.springframework.org/schema/context/spring-context.xsd"> 15 16 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 17 <property name="driverClassName" value="${jdbc.driverClassName}"/> 18 <property name="url" value="${jdbc.url}"/> 19 <property name="username" value="${jdbc.username}"/> 20 <property name="password" value="${jdbc.password}"/> 21 </bean> 22 23 <!-- jdbc事务管理器 --> 24 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 25 <property name="dataSource" ref="dataSource"></property> 26 </bean> 27 28 <tx:annotation-driven transaction-manager="transactionManager"/> 29 30 <context:property-placeholder location="jdbc.properties"/> 31 32 <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"> 33 <constructor-arg ref="dataSource"></constructor-arg> 34 </bean> 35 36 37 <bean id="bankDao" class="com.wishwzp.dao.impl.BankDaoImpl"> 38 <property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"></property> 39 </bean> 40 41 <bean id="bankService" class="com.wishwzp.service.impl.BankServiceImpl"> 42 <property name="bankDao" ref="bankDao"></property> 43 </bean> 44 45 </beans>
jdbc.properties:
1 jdbc.driverClassName=com.mysql.jdbc.Driver 2 jdbc.url=jdbc:mysql://localhost:3306/db_bank?characterEncoding=utf-8 3 jdbc.username=root 4 jdbc.password=123456
BankServiceImpl.java:
1 package com.wishwzp.service.impl; 2 3 4 import org.springframework.transaction.annotation.Transactional; 5 6 import com.wishwzp.dao.BankDao; 7 import com.wishwzp.service.BankService; 8 9 @Transactional 10 public class BankServiceImpl implements BankService{ 11 12 private BankDao bankDao; 13 14 public void setBankDao(BankDao bankDao) { 15 this.bankDao = bankDao; 16 } 17 18 19 @Override 20 public void transferAccounts(int count, int userIdA, int userIdB) { 21 // TODO Auto-generated method stub 22 // TODO Auto-generated method stub 23 bankDao.outMoney(count, userIdA); 24 bankDao.inMoney(count, userIdB); 25 } 26 27 }
BankService.java:
1 package com.wishwzp.service; 2 3 public interface BankService { 4 5 /** 6 * A向B转账count元 7 * @param count 8 * @param userIdA 9 * @param userIdB 10 */ 11 public void transferAccounts(int count,int userIdA,int userIdB); 12 }
BankDaoImpl.java:
1 package com.wishwzp.dao.impl; 2 3 import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; 4 import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; 5 6 import com.wishwzp.dao.BankDao; 7 8 public class BankDaoImpl implements BankDao{ 9 10 private NamedParameterJdbcTemplate namedParameterJdbcTemplate; 11 12 13 public void setNamedParameterJdbcTemplate( 14 NamedParameterJdbcTemplate namedParameterJdbcTemplate) { 15 this.namedParameterJdbcTemplate = namedParameterJdbcTemplate; 16 } 17 18 @Override 19 public void inMoney(int money, int userId) { 20 // TODO Auto-generated method stub 21 String sql="update t_count2 set count=count+:money where userId=:userId"; 22 MapSqlParameterSource sps=new MapSqlParameterSource(); 23 sps.addValue("money", money); 24 sps.addValue("userId", userId); 25 namedParameterJdbcTemplate.update(sql,sps); 26 } 27 28 @Override 29 public void outMoney(int money, int userId) { 30 // TODO Auto-generated method stub 31 String sql="update t_count set count=count-:money where userId=:userId"; 32 MapSqlParameterSource sps=new MapSqlParameterSource(); 33 sps.addValue("money", money); 34 sps.addValue("userId", userId); 35 namedParameterJdbcTemplate.update(sql,sps); 36 } 37 38 }
BankDao.java:
1 package com.wishwzp.dao; 2 3 public interface BankDao { 4 5 public void inMoney(int money,int userId); 6 7 public void outMoney(int money,int userId); 8 }
运行结果显示:
第四节:事务传播行为
事务传播行为:Spring 中,当一个service 方法调用另外一个service 方法的时候,因为每个service 方法都有事务,这时候就出现了事务的嵌套;由此,就产生了事务传播行为;
在Spring 中,通过配置Propagation,来定义事务传播行为;
PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
--------------------------------------------------------------------------------------------------------------------------------
<tx:attributes>
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="edit*" propagation="REQUIRED" />
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="new*" propagation="REQUIRED" />
<tx:method name="set*" propagation="REQUIRED" />
<tx:method name="remove*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="change*" propagation="REQUIRED" />
<tx:method name="get*" propagation="REQUIRED" read-only="true" />
<tx:method name="find*" propagation="REQUIRED" read-only="true" />
<tx:method name="load*" propagation="REQUIRED" read-only="true" />
<tx:method name="*" propagation="REQUIRED" read-only="true" />
</tx:attributes>
----------------------------------------------------------------------------------------------------------------------------
我们一般在项目中使用的是:使用XML 配置声明式事务。。。。。。。。。
为了增强性。。。其他不需要改变,只需要改一下beans.xml的配置文件
beans.xml:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xmlns:tx="http://www.springframework.org/schema/tx" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans.xsd 9 http://www.springframework.org/schema/aop 10 http://www.springframework.org/schema/aop/spring-aop.xsd 11 http://www.springframework.org/schema/tx 12 http://www.springframework.org/schema/tx/spring-tx.xsd 13 http://www.springframework.org/schema/context 14 http://www.springframework.org/schema/context/spring-context.xsd"> 15 16 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 17 <property name="driverClassName" value="${jdbc.driverClassName}"/> 18 <property name="url" value="${jdbc.url}"/> 19 <property name="username" value="${jdbc.username}"/> 20 <property name="password" value="${jdbc.password}"/> 21 </bean> 22 23 <!-- jdbc事务管理器 --> 24 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 25 <property name="dataSource" ref="dataSource"></property> 26 </bean> 27 28 <!-- 配置事务通知 --> 29 <tx:advice id="txAdvice" transaction-manager="transactionManager"> 30 <tx:attributes> 31 <tx:method name="insert*" propagation="REQUIRED" /> 32 <tx:method name="update*" propagation="REQUIRED" /> 33 <tx:method name="edit*" propagation="REQUIRED" /> 34 <tx:method name="save*" propagation="REQUIRED" /> 35 <tx:method name="add*" propagation="REQUIRED" /> 36 <tx:method name="new*" propagation="REQUIRED" /> 37 <tx:method name="set*" propagation="REQUIRED" /> 38 <tx:method name="remove*" propagation="REQUIRED" /> 39 <tx:method name="delete*" propagation="REQUIRED" /> 40 <tx:method name="change*" propagation="REQUIRED" /> 41 <tx:method name="get*" propagation="REQUIRED" read-only="true" /> 42 <tx:method name="find*" propagation="REQUIRED" read-only="true" /> 43 <tx:method name="load*" propagation="REQUIRED" read-only="true" /> 44 <tx:method name="*" propagation="REQUIRED" read-only="true" /> 45 </tx:attributes> 46 </tx:advice> 47 48 <!-- 配置事务切面 --> 49 <aop:config> 50 <!-- 配置切点 --> 51 <aop:pointcut id="serviceMethod" expression="execution(* com.wishwzp.service.*.*(..))" /> 52 <!-- 配置事务通知 --> 53 <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/> 54 </aop:config> 55 56 57 58 <context:property-placeholder location="jdbc.properties"/> 59 60 <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"> 61 <constructor-arg ref="dataSource"></constructor-arg> 62 </bean> 63 64 65 <bean id="bankDao" class="com.wishwzp.dao.impl.BankDaoImpl"> 66 <property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"></property> 67 </bean> 68 69 <bean id="bankService" class="com.wishwzp.service.impl.BankServiceImpl"> 70 <property name="bankDao" ref="bankDao"></property> 71 </bean> 72 73 </beans>