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的事务 首先,大家已经知道了,事务说白了就是一个词----统 ...
随机推荐
- 总结的Javascript插件
1.很好用的弹窗 https://limonte.github.io/sweetalert2/ https://github.com/limonte/sweetalert2 import './unt ...
- ASP.NET MVC编程——缓存
Web缓存分为服务端缓存和客户端缓存. 1 服务端缓存 1.1请求域内的缓存:HttpContext.Items 类型: HttpContext.Items的类型为IDictionary,且键和值都是 ...
- JavaScript(第一天)【<script>标签浅析】
一.创建一张HTML页面 初学者创建一张html页面建议借助工具,例如Dreamweaver可视化编辑器. 二.<Script>标签解析 <script>xxx</s ...
- 第1次作业:no blog no fun
1.先回答老师的问题 第一部分:结缘计算机 读了进入2012 -- 回顾我走过的编程之路后,我试着回顾了我的编程生涯的开始.我最原始的记忆就是老爸教我用电脑玩连连看,那时候的显示器应该是C ...
- [高级软件工程教学]团队Beta阶段成绩汇总
一.作业地址: https://edu.cnblogs.com/campus/fzu/AdvancedSoftwareEngineering/homework/1501 二.Beta冲刺课堂答辩 1. ...
- Beta敏捷冲刺每日报告——Day5
1.情况简述 Beta阶段Scrum Meeting 敏捷开发起止时间 2017.11.6 00:00 -- 2017.11.7 00:00 讨论时间地点 2017.11.6 早9:30,电话会议会议 ...
- 从0开始的LeetCode生活—9. Palindrome Number(回文数)
题目大意: 判断输入的数字是不是回文数.所谓回文数就是正反读都一样的数字,比如说11,121,1221这样子的数字.负数不会是回文数. 解题思路: 思路一:如果这个数是负数,则返回false,否则用一 ...
- Git学习使用
1.注册码云并建立远程仓库 2.安装git 3.使用eclipse egit 推送以及克隆 建立本地仓库,成功后如图 推送项目至本地仓库与远程仓库 使用右键菜单team-share 选项,与仓库关联后 ...
- django报错Manager isn't accessible via UserInfo instances
出现这种错误是因为调用模型对象时使用了变量名,而不是对象名(模型类),例如: user = UserInfo()user_li = user.objects.filter(uname=username ...
- Mego(08) - 高级建模
对于模型建立Mego还提供了一些高级主题 数据库函数映射 我们可以将现有的CLR方法映射到指定数据库的标题函数上,如下所示 public class OrderManageEntities : DbC ...