Spring事务
一、Spring事务接口
spring事务提供了三个主要的接口PlatformTransactionManager、TransactionDefination定义事务隔离级别、TransactionDefination定义事务传播行为、TransactionStatus接口。
PlatformTransactionManager:事务管理器。
TransactionDefination:定义事务隔离级别:READ_UNCOMMITED、READ_COMMITTED、REPEATABLE_READ、SERIALIZABLE。mysql数据库默认的是REPEATABLE_READ级别4.
TransactionDefination:定义事务传播行为:PROPAGATION_REQUIRED、PROPAGATION_SUPPORTS、PROPAGATION_MANDATORY、PROPAGATION_REQUIRES_REW、PROPAGATION_NOT_SUPPORTED、PROPAGATION_NEVER、PROPAGATION_NESTED等
二、spring事务管理--转账案例
2.1、环境搭建
引入相关jar包、jdbc.properties、log4j.properties等
AccountService接口、AccountServiceImpl实现类
AccountDao接口、AccountDaoImpl实现类
AccountService.java接口
1: package com.spring.demo1;2:3: public interface AccountService {4: public void transfer(String OutName,String InName,Double money);5: }6:AccountDao.java接口:
1: package com.spring.demo1;2: public interface AccountDao {3: public void outMoney(String OutName,Double money);4: public void inMoney(String InName,Double money);5: }6:AccountDaoImpl.java
1: package com.spring.demo1;2:3: import org.springframework.jdbc.core.support.JdbcDaoSupport;4: public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {5:6: public void inMoney(String InName, Double money) {7: // TODO Auto-generated method stub8: String sql="update account set money=money + ? where name= ?";9: this.getJdbcTemplate().update(sql,money,InName);10: }11:12: public void outMoney(String OutName, Double money) {13: // TODO Auto-generated method stub14: String sql="update account set money=money - ? where name= ?";15: this.getJdbcTemplate().update(sql,money,OutName);16: }17:18: }19:
2.2、编程式事务管理
ApplicationContex.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" xmlns:p="http://www.springframework.org/schema/p"4: xmlns:context="http://www.springframework.org/schema/context"5: xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"6: xsi:schemaLocation="http://www.springframework.org/schema/beans7: http://www.springframework.org/schema/beans/spring-beans-3.0.xsd8: http://www.springframework.org/schema/context9: http://www.springframework.org/schema/context/spring-context-3.0.xsd10: http://www.springframework.org/schema/tx11: http://www.springframework.org/schema/tx/spring-tx-3.0.xsd12: http://www.springframework.org/schema/aop13: http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">14:15:16: <!-- 引入外部的属性文件 -->17: <context:property-placeholder location="classpath:jdbc.properties" />18:19: <!-- 配置c3p0连接池20: <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"21: p:driverClass="${jdbc.driverClass}"22: p:jdbcUrl="${jdbc.url}"23: p:user="${jdbc.username}"24: p:password="${jdbc.password}" />-->25:26: <!-- 配置dbcp连接池 -->27: <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"28: destroy-method="close"29: p:driverClassName="${jdbc.driverClass}"30: p:url="${jdbc.url}"31: p:username="${jdbc.username}"32: p:password="${jdbc.password}" />33:34: <!-- 配置Jdbc模板 -->35: <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"36: p:dataSource-ref="dataSource" />37:38: <!-- 业务层 -->39: <bean id="accountService" class="com.spring.demo4.AccountServiceImpl" p:accountDao-ref="accountDao"/>40:41: <!-- Dao类 -->42: <bean id="accountDao" class="com.spring.demo4.AccountDaoImpl" p:dataSource-ref="dataSource" />43:44: <!-- 配置事务管理器 -->45: <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"46: p:dataSource-ref="dataSource" />47:48: <!-- 定义一个事务管理模板 :spring为了简化事务管理的代码而提供的类-->49: <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"50: p:transactionManager-ref="transactionManager" />51:52: </beans>53:AccountServiceImpl.java
1: package com.spring.demo1;2:3: import org.springframework.transaction.TransactionStatus;4: import org.springframework.transaction.support.TransactionCallback;5: import org.springframework.transaction.support.TransactionCallbackWithoutResult;6: import org.springframework.transaction.support.TransactionTemplate;7: import com.sun.istack.internal.FinalArrayList;8: public class AccountServiceImpl implements AccountService {9:10: //注入转账的DAO类11:12: private AccountDao accountDao;13: public void setAccountDao(AccountDao accountDao) {14: this.accountDao = accountDao;15: }16:17: //注入事务管理的模板18: private TransactionTemplate transactionTemplate;19: public void setTransactionTemplate(TransactionTemplate transactionTemplate) {20: this.transactionTemplate = transactionTemplate;21: }22:23: public AccountDao getAccountDao() {24: return accountDao;25: }26:27: public TransactionTemplate getTransactionTemplate() {28: return transactionTemplate;29: }30:31: public void transfer(final String OutName,final String InName,final Double money) {32: // TODO Auto-generated method stub33: transactionTemplate.execute(new TransactionCallbackWithoutResult() {34: @Override35: protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {36: // TODO Auto-generated method stub37: accountDao.outMoney(OutName, money);38: accountDao.inMoney(InName, money);39: }40: });41:42: }43:44: }45:测试类:springtestdemo1.java
1: package com.spring.demo1;2:3: import javax.annotation.Resource;4: import org.junit.Test;5: import org.junit.runner.RunWith;6: import org.springframework.test.context.ContextConfiguration;7: import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;8: @RunWith(SpringJUnit4ClassRunner.class)9: @ContextConfiguration("classpath:applicationContext.xml")10: public class springtestdemo1 {11: //测试业务层类:12: @Resource(name="accountService")13: private AccountService accountService;14: @Test15: public void demo1(){16: accountService.transfer("aaa", "bbb", 200d);17: }18: }19:运行结果:
当修改一下AccountServiceImpl.java的代码
1: accountDao.outMoney(OutName, money);2: int i=1 / 0;3: accountDao.inMoney(InName, money);当不引入事务管理的运行结果: 发现用户aaa已经少了300块,但是用户bbb却没有增加.
当引入事务管理的运行结果: 这时候,用户aaa和bbb不会出现不一致的情况
2.3、声明式事务管理方式一:TransactionProxyFactoryBean
ApplicationContext2.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" xmlns:p="http://www.springframework.org/schema/p"4: xmlns:context="http://www.springframework.org/schema/context"5: xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"6: xsi:schemaLocation="http://www.springframework.org/schema/beans7: http://www.springframework.org/schema/beans/spring-beans-3.0.xsd8: http://www.springframework.org/schema/context9: http://www.springframework.org/schema/context/spring-context-3.0.xsd10: http://www.springframework.org/schema/tx11: http://www.springframework.org/schema/tx/spring-tx-3.0.xsd12: http://www.springframework.org/schema/aop13: http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">14:15: <!-- 引入外部的属性文件 -->16: <context:property-placeholder location="classpath:jdbc.properties" />17:18: <!-- 配置c3p0连接池19: <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"20: p:driverClass="${jdbc.driverClass}"21: p:jdbcUrl="${jdbc.url}"22: p:user="${jdbc.username}"23: p:password="${jdbc.password}" />-->24:25: <!-- 配置dbcp连接池 -->26: <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"27: destroy-method="close"28: p:driverClassName="${jdbc.driverClass}"29: p:url="${jdbc.url}"30: p:username="${jdbc.username}"31: p:password="${jdbc.password}" />32:33: <!-- 配置Jdbc模板 -->34: <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"35: p:dataSource-ref="dataSource" />36:37: <!-- 业务层 -->38: <bean id="accountService" class="com.spring.demo4.AccountServiceImpl" p:accountDao-ref="accountDao"/>39:40: <!-- Dao类 -->41: <bean id="accountDao" class="com.spring.demo4.AccountDaoImpl" p:dataSource-ref="dataSource" />42:43: <!-- 配置事务管理器 -->44: <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"45: p:dataSource-ref="dataSource" />46:47: <!-- 配置业务层的代理 -->48: <!-- prop的格式:49: PROPAGATION:事务的传播行为50: ISOLATION : 事务的隔离级别51: readOnly: 只读52: -Exception :发生哪些异常,回滚事务53: +Exception:发生哪些异常,事务不回滚54: -->55: <bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">56: <!-- 配置目标对象 -->57: <property name="target" ref="accountService" />58: <!-- 事务事务管理器 -->59: <property name="transactionManager" ref="transactionManager" />60: <!-- 注入事务的一些属性 -->61: <property name="transactionAttributes" >62: <props>63: <prop key="transfer">PROPAGATION_REQUIRED,+java.lang.ArithmeticException</prop>64: </props>65: </property>66: </bean>67: </beans>AccountServiceImpl.java
1: package com.spring.demo2;2: import org.springframework.transaction.TransactionStatus;3: import org.springframework.transaction.support.TransactionCallback;4: import org.springframework.transaction.support.TransactionCallbackWithoutResult;5: import org.springframework.transaction.support.TransactionTemplate;6: import com.sun.istack.internal.FinalArrayList;7: public class AccountServiceImpl implements AccountService {8: //注入转账的DAO类9: private AccountDao accountDao;10: public void setAccountDao(AccountDao accountDao) {11: this.accountDao = accountDao;12: }13: public void transfer(String OutName, String InName, Double money) {14: // TODO Auto-generated method stub15: accountDao.outMoney(OutName, money);16: int i=1/0;17: accountDao.inMoney(InName, money);18: }19: }20:测试类:springtestdemo2.java
1: package com.spring.demo2;2: import javax.annotation.Resource;3: import org.junit.Test;4: import org.junit.runner.RunWith;5: import org.springframework.test.context.ContextConfiguration;6: import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;7: /**8: * 声明式9: *10: * @author su11: *12: */13: @RunWith(SpringJUnit4ClassRunner.class)14: @ContextConfiguration("classpath:applicationContext2.xml")15: public class springtestdemo2 {16: //测试业务层类:17: /**18: *19: * 注入代理类:因为代理类已经增强了20: */21: //@Resource(name="accountService")22: @Resource(name="accountServiceProxy")23: private AccountService accountService;24: @Test25: public void test(){26: accountService.transfer("aaa", "bbb", 300d);27: }28: }运行结果图上。
2.4、声明式事务管理方式二:基于AspectJ的xml配置
ApplicationContex3.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" xmlns:p="http://www.springframework.org/schema/p"4: xmlns:context="http://www.springframework.org/schema/context"5: xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"6: xsi:schemaLocation="http://www.springframework.org/schema/beans7: http://www.springframework.org/schema/beans/spring-beans-3.0.xsd8: http://www.springframework.org/schema/context9: http://www.springframework.org/schema/context/spring-context-3.0.xsd10: http://www.springframework.org/schema/tx11: http://www.springframework.org/schema/tx/spring-tx-3.0.xsd12: http://www.springframework.org/schema/aop13: http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">14:15: <!-- 引入外部的属性文件 -->16: <context:property-placeholder location="classpath:jdbc.properties" />17:18: <!-- 配置c3p0连接池19: <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"20: p:driverClass="${jdbc.driverClass}"21: p:jdbcUrl="${jdbc.url}"22: p:user="${jdbc.username}"23: p:password="${jdbc.password}" />-->24:25: <!-- 配置dbcp连接池 -->26: <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"27: destroy-method="close"28: p:driverClassName="${jdbc.driverClass}"29: p:url="${jdbc.url}"30: p:username="${jdbc.username}"31: p:password="${jdbc.password}" />32:33: <!-- 配置Jdbc模板 -->34: <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"35: p:dataSource-ref="dataSource" />36:37: <!-- 业务层 -->38: <bean id="accountService" class="com.spring.demo4.AccountServiceImpl" p:accountDao-ref="accountDao"/>39:40: <!-- Dao类 -->41: <bean id="accountDao" class="com.spring.demo4.AccountDaoImpl" p:dataSource-ref="dataSource" />42:43: <!-- 配置事务管理器 -->44: <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"45: p:dataSource-ref="dataSource" />46:47: <!-- 配置事务的通知:(事务的增强增强) -->48: <tx:advice id="txAdvice" transaction-manager="transactionManager">49: <tx:attributes>50: <!-- propagation:事务的传播行为51: isolation: 事务的隔离级别52: read-only:只读53: rollback-for:发生哪些异常回滚54: no-rollback-for:发生哪些异常不回滚55: -->56: <tx:method name="transfer" propagation="REQUIRED"/>57: </tx:attributes>58: </tx:advice>59:60: <!-- 配置切面 -->61: <aop:config>62: <!-- 配置切入点 -->63: <aop:pointcut expression="execution(* com.spring.demo3.AccountService+.*(..))" id="pointcut1" />64: <!-- 配置切面 -->65: <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1" />66: </aop:config>67: </beans>AccountServiceImpl.java
1: package com.spring.demo3;2: import org.springframework.transaction.TransactionStatus;3: import org.springframework.transaction.annotation.Transactional;4: import org.springframework.transaction.support.TransactionCallback;5: import org.springframework.transaction.support.TransactionCallbackWithoutResult;6: import org.springframework.transaction.support.TransactionTemplate;7: import com.sun.istack.internal.FinalArrayList;8: public class AccountServiceImpl implements AccountService {9: //注入转账的DAO类10: private AccountDao accountDao;11: public void setAccountDao(AccountDao accountDao) {12: this.accountDao = accountDao;13: }14: public void transfer(String OutName, String InName, Double money) {15: // TODO Auto-generated method stub16: accountDao.outMoney(OutName, money);17: // int i=1/0;18: accountDao.inMoney(InName, money);19: }20: }测试类:springtestdemo3.java
1: package com.spring.demo3;2:3: import javax.annotation.Resource;4: import org.junit.Test;5: import org.junit.runner.RunWith;6: import org.springframework.test.context.ContextConfiguration;7: import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;8: /**9: * 声明式:基于AspectJ的XML的配置10: *11: * @author su12: *13: */14: @RunWith(SpringJUnit4ClassRunner.class)15: @ContextConfiguration("classpath:applicationContext3.xml")16: public class springtestdemo3 {17: //测试业务层类:18: @Resource(name="accountService")19: private AccountService accountService;20: @Test21: public void test(){22: accountService.transfer("aaa", "bbb", 300d);23: }24: }
2.5、声明式事务管理方式三:基于@Transactional注解
ApplicationContext4.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" xmlns:p="http://www.springframework.org/schema/p"4: xmlns:context="http://www.springframework.org/schema/context"5: xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"6: xsi:schemaLocation="http://www.springframework.org/schema/beans7: http://www.springframework.org/schema/beans/spring-beans-3.0.xsd8: http://www.springframework.org/schema/context9: http://www.springframework.org/schema/context/spring-context-3.0.xsd10: http://www.springframework.org/schema/tx11: http://www.springframework.org/schema/tx/spring-tx-3.0.xsd12: http://www.springframework.org/schema/aop13: http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">14:15: <!-- 引入外部的属性文件 -->16: <context:property-placeholder location="classpath:jdbc.properties" />17:18: <!-- 配置c3p0连接池19: <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"20: p:driverClass="${jdbc.driverClass}"21: p:jdbcUrl="${jdbc.url}"22: p:user="${jdbc.username}"23: p:password="${jdbc.password}" />-->24:25: <!-- 配置dbcp连接池 -->26: <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"27: destroy-method="close"28: p:driverClassName="${jdbc.driverClass}"29: p:url="${jdbc.url}"30: p:username="${jdbc.username}"31: p:password="${jdbc.password}" />32:33: <!-- 配置Jdbc模板 -->34: <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"35: p:dataSource-ref="dataSource" />36:37: <!-- 业务层 -->38: <bean id="accountService" class="com.spring.demo4.AccountServiceImpl" p:accountDao-ref="accountDao"/>39:40: <!-- Dao类 -->41: <bean id="accountDao" class="com.spring.demo4.AccountDaoImpl" p:dataSource-ref="dataSource" />42:43: <!-- 配置事务管理器 -->44: <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"45: p:dataSource-ref="dataSource" />46:47: <!-- 开启注解事务 -->48: <tx:annotation-driven transaction-manager="transactionManager"/>49: </beans>AccountServiceImpl.java
1: package com.spring.demo4;2: import org.springframework.transaction.TransactionStatus;3: import org.springframework.transaction.annotation.Isolation;4: import org.springframework.transaction.annotation.Propagation;5: import org.springframework.transaction.annotation.Transactional;6: import org.springframework.transaction.support.TransactionCallback;7: import org.springframework.transaction.support.TransactionCallbackWithoutResult;8: import org.springframework.transaction.support.TransactionTemplate;9: import com.sun.istack.internal.FinalArrayList;10: /**11: * @Transactional:注解中的属性12: * propagation:事务的传播行为13: * isolation: 事务的隔离级别14: * readOnly:只读15: * rollbackFor:发生哪些异常回滚16: * noRollbackFor:发生哪些异常不回滚17: *18: * @author su19: *20: */21: @Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT,readOnly=false)22: public class AccountServiceImpl implements AccountService {23:24: //注入转账的DAO类25:26: private AccountDao accountDao;27: public void setAccountDao(AccountDao accountDao) {28: this.accountDao = accountDao;29: }30:31: public void transfer(String OutName, String InName, Double money) {32: // TODO Auto-generated method stub33: accountDao.outMoney(OutName, money);34: // int i=1/0;35: accountDao.inMoney(InName, money);36: }37: }测试类:springtestdemo4.java
1: package com.spring.demo4;2: import javax.annotation.Resource;3: import org.junit.Test;4: import org.junit.runner.RunWith;5: import org.springframework.test.context.ContextConfiguration;6: import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;7: /**8: * 声明式:基于注解的事务管理方式9: *10: * @author su11: *12: */13: @RunWith(SpringJUnit4ClassRunner.class)14: @ContextConfiguration("classpath:applicationContext4.xml")15: public class springtestdemo4 {16:17: //测试业务层类:18: @Resource(name="accountService")19: private AccountService accountService;20: @Test21: public void test(){22: accountService.transfer("aaa", "bbb", 300d);23: }24: }






浙公网安备 33010602011771号