Spring之事务管理
Connection conn = null; try{ conn = getConnection(); conn.setAutoCommit(false); //关闭事务的自动提交 A B C D conn.commit(); }catch(){ conn.rollback(); }
Connection conn = null; Savepoint savepoint = null; try{ conn = getConnection(); conn.setAutoCommit(false); //关闭事务的自动提交 A B savepoint = conn.setSavepoint(); C D conn.commit(); }catch(){ if(savepoint != null){ //savepoint不为空,说明已经执行到了C或者D conn.rollback(savepoint); //回滚到保存点 }else{ conn.rollback(); //savepoing为空,说明在执行A或者B的时候就抛了异常 } }


1. dao层
package cn.african.dao; public interface BankDao { boolean transfer(Long fromId, Long toId, double amount); } package cn.african.dao; import org.springframework.jdbc.core.support.JdbcDaoSupport; public class BankDaoImpl extends JdbcDaoSupport implements BankDao { @Override public boolean transfer(Long fromId, Long toId, double amount) { int f = this.getJdbcTemplate().update("update account set money = money - ? where id = ?", amount, fromId); //异常 int i = 1 / 0; int t = this.getJdbcTemplate().update("update account set money = money + ? where id = ?", amount, toId); if(f > 0 && t > 0) { return true; } return false; } }
2. service层
package cn.african.service; public interface BankService { public boolean transfer(Long fromId, Long toId, double amount); } package cn.african.service; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import cn.african.dao.BankDao; public class BankServiceImpl implements BankService { private BankDao bankDao; //事务详情 private TransactionDefinition txDefinition; //事务管理器 private PlatformTransactionManager txManager; @Override public boolean transfer(Long fromId, Long toId, double amount) { TransactionStatus txStatus = txManager.getTransaction(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("转账失败"); } return result; } public void setBankDao(BankDao bankDao) { this.bankDao = bankDao; } public void setTxDefinition(TransactionDefinition txDefinition) { this.txDefinition = txDefinition; } public void setTxManager(PlatformTransactionManager txManager) { this.txManager = txManager; } }
3. applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/txdemo" /> <property name="user" value="root" /> <property name="password" value="123456" /> </bean> <bean id="bankDao" class="cn.african.dao.BankDaoImpl"> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="bankService" class="cn.african.service.BankServiceImpl"> <property name="bankDao" ref="bankDao" /> <property name="txManager" ref="txManager" /> <!-- 定义事务详情 --> <property name="txDefinition"> <bean class="org.springframework.transaction.support.DefaultTransactionDefinition"> <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED" /> </bean> </property> </bean> </beans>
4. 测试类
package cn.african.test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.african.service.BankService; public class TestApp { @Test public void demo01() throws Exception { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); BankService bankService = context.getBean("bankService", BankService.class); bankService.transfer(1L, 2L, 1000D); context.getClass().getMethod("close").invoke(context); } }
package cn.african.service; public interface BankService { public boolean transfer(Long fromId, Long toId, double amount); } package cn.african.service; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionTemplate; import cn.african.dao.BankDao; public class BankServiceImpl implements BankService { private BankDao bankDao; private TransactionTemplate transactionTemplate; @Override public boolean transfer(Long fromId, Long toId, double amount) { return transactionTemplate.execute(new TransactionCallback<Boolean>() { boolean result = false; @Override public Boolean doInTransaction(TransactionStatus status) { try { bankDao.transfer(fromId, toId, amount); result = true; } catch (Exception e) { //设置回滚 status.setRollbackOnly(); System.out.println("转账失败"); } return result; } }); } public void setBankDao(BankDao bankDao) { this.bankDao = bankDao; } public void setTransactionTemplate(TransactionTemplate transactionTemplate) { this.transactionTemplate = transactionTemplate; } }
3. applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/txdemo" /> <property name="user" value="root" /> <property name="password" value="123456" /> </bean> <bean id="bankDao" class="cn.african.dao.BankDaoImpl"> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="bankService" class="cn.african.service.BankServiceImpl"> <property name="bankDao" ref="bankDao"></property> <property name="transactionTemplate" ref="txTemplate"></property> </bean> <bean id="txTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="txManager"></property> </bean> </beans>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ee19_spring_day03" /> <property name="user" value="root" /> <property name="password" value="123456" /> </bean> <bean id="bankDao" class="cn.african.dao.BankDaoImpl"> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!--这个事务拦截器就是切面--> <bean id="txInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <property name="transactionManager" ref="txManager"/> <property name="transactionAttributes"> <props> <prop key="transfer">PROPAGATION_REQUIRED</prop> </props> </property> </bean> <bean id="bankServiceTarget" class="cn.african.service.BankServiceImpl"> <property name="bankDao" ref="bankDao"/> </bean> <bean id="bankService" class="org.springframework.aop.framework.ProxyFactoryBean"> <!--目标类--> <property name="target" ref="bankServiceTarget"/> <!--配置切面--> <property name="interceptorNames"> <list> <idref bean="txInterceptor"/> </list> </property> </bean> </beans>
传播行为 [,隔离级别] [,只读属性] [,超时属性] [不影响提交的异常] [,导致回滚的异常]
<prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED,TIMEOUT_20,+AException,+BException,-CException</prop>
package cn.african.service; import cn.african.dao.BankDao; public class BankServiceImpl implements BankService { private BankDao bankDao; @Override public boolean transfer(Long fromId, Long toId, double amount) { //这种方式,在这里不能自己去捕获异常,这个异常必须由spring感知 return bankDao.transfer(fromId, toId, amount); } public void setBankDao(BankDao bankDao) { this.bankDao = bankDao; } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ee19_spring_day03" /> <property name="user" value="root" /> <property name="password" value="123456" /> </bean> <bean id="bankDao" class="cn.african.dao.BankDaoImpl"> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="bankServiceTarget" class="cn.african.service.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="txManager"/> <property name="transactionAttributes"> <props> <prop key="transfer">PROPAGATION_REQUIRED</prop> </props> </property> </bean> </beans>
<?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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ee19_spring_day03" /> <property name="user" value="root" /> <property name="password" value="123456" /> </bean> <bean id="bankDao" class="cn.african.dao.BankDaoImpl"> <property name="dataSource" ref="dataSource"/> </bean> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <bean id="bankService" class="cn.african.service.BankServiceImpl"> <property name="bankDao" ref="bankDao"/> </bean> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="transfer" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <!--如果事务的默认配置就能满足需求,上面元素的配置可以简化为以下方式--> <!-- <tx:advice id="txAdvice" transaction-manager="txManager" /> --> <aop:config> <aop:pointcut expression="execution(* cn.african.service..*.*(..))" id="txPointcut"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/> </aop:config> </beans>
<?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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ee19_spring_day03" /> <property name="user" value="root" /> <property name="password" value="123456" /> </bean> <bean id="bankDao" class="cn.african.dao.BankDaoImpl"> <property name="dataSource" ref="dataSource"/> </bean> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <bean id="bankService" class="cn.african.service.BankServiceImpl"> <property name="bankDao" ref="bankDao"/> </bean> <!-- 使用事务注解时,必须要开启注解驱动 --> <tx:annotation-driven transaction-manager="txManager"/> </beans>
Spring之事务管理的更多相关文章
- Spring的事务管理
事务 事务:是逻辑上一组操作,要么全都成功,要么全都失败. 事务特性(ACID) 原子性:事务不可分割 一致性:事务执行的前后,数据完整性保持一致 隔离性:一个事务执行的时候,不应该受到其他事务的打扰 ...
- spring笔记--事务管理之声明式事务
事务简介: 事务管理是企业级应用开发中必不可少的技术,主要用来确保数据的完整性和一致性, 事务:就是一系列动作,它们被当作一个独立的工作单元,这些动作要么全部完成,要么全部不起作用. Spring中使 ...
- Spring应用——事务管理
事务基础:请参看:http://www.cnblogs.com/solverpeng/p/5720306.html 一.Spring 事务管理 1.前提:事务管理器 在使用 Spring 声明式事务管 ...
- spring+mybatis事务管理
spring+mybatis事务管理 最近在和朋友做一个项目,考虑用springmvc+mybatis来做,之前在公司工作吧,对于数据库这块的配置也有人再弄,最近因为这个项目,我就上网学习了一些关于数 ...
- spring,mybatis事务管理配置与@Transactional注解使用[转]
spring,mybatis事务管理配置与@Transactional注解使用[转] spring,mybatis事务管理配置与@Transactional注解使用 概述事务管理对于企业应用来说是至关 ...
- Spring高级事务管理难点剖析
1Spring事务传播行为 所谓事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播.Spring支持7种事务传播行为 PROPAGATION_REQUIRED(加入已有事务) 如果当前没 ...
- CSDN上看到的一篇有关Spring JDBC事务管理的文章(内容比较全) (转)
JDBC事务管理 Spring提供编程式的事务管理(Programmatic transaction manage- ment)与声明式的事务管理(Declarative transaction ma ...
- Mybatis整合Spring实现事务管理的源码分析
一:前言 没有完整看完,但是看到了一些关键的地方,这里做个记录,过程会有点乱,以后逐渐补充最终归档为完整流程:相信看过框架源码的都知道过程中无法完全确定是怎样的流程,毕竟不可能全部都去测试一遍 ,但是 ...
- Hibernate与Spring的事务管理
什么是事务 这个问题比较大,按照我的理解就是,一个事务内的n个操作,要么全部完成,一旦有一个操作有问题,那么所有的操作都全部回滚. Jdbc的事务 首先,大家已经知道了,事务说白了就是一个词----统 ...
随机推荐
- Mycat 配置说明(server.xml)
server.xml 几乎保存了所有mycat需要的系统配置信息,包括 mycat 用户管理.DML权限管理等,其在代码内直接的映射类为SystemConfig 类. user 标签 该标签主要用于定 ...
- 笔记:Maven 项目基本配置
Maven 的基本设置包含项目基本信息和项目信息,基本信息主要用于设置当前包的归属项目.当前项目等,配置文件结构如下: <project xmlns="http://maven.apa ...
- kvm之三:本地安装虚拟机
1.格式化新添加的磁盘 [root@kvm ~ ::]#fdisk /dev/sdb Command (m for help): n //新建分区 Command action e extended ...
- Alpha冲刺Day6
Alpha冲刺Day6 一:站立式会议 今日安排: 由张梨贤继续完成前一天委托第三方剩余的内容,并完成委托情况查看这一子模块 由黄腾飞继续完成前一天企业自查风险管理剩余的内容,并完成风险上报这一子模块 ...
- (转)如何在Eclipse中查看JDK类库的源代码
在Eclipse中查看JDK类库的源代码!!! 设置: 1.点 “window”-> "Preferences" -> "Java" -> & ...
- 201421123042 《Java程序设计》第14周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结与数据库相关内容. 答: 2. 使用数据库技术改造你的系统 2.1 简述如何使用数据库技术改造你的系统.要建立什么表?截图你的表设计 ...
- bzoj千题计划165:bzoj5127: 数据校验
http://www.lydsy.com/JudgeOnline/upload/201712/prob12.pdf 区间的任意一个子区间都满足值域连续 等价于 区间任意一个长为2的子区间都满足值域连续 ...
- [ZLXOI2015]殉国
2057. [ZLXOI2015]殉国 http://cogs.pro/cogs/problem/problem.php?pid=2057 ★☆ 输入文件:BlackHawk.in 输出文件: ...
- PHP获取短信验证码
PHP如何获取短信验证码?以下是创蓝253短信平台下的PHP接口代码案例: <?php header("Content-type:text/html; charset=UTF-8& ...
- 技术文档分享_linux中生成考核用的GPT分区表结构修复
注:历史版本,后期改用python实现了 实验一: 目的:用于生成大量模拟破坏GPT分区结构案例,并生成唯一方式修复后的评判方法.故障:在一个完整的GPT分区磁盘上,丢失了GPT主分区表,或备份分区表 ...