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的事务 首先,大家已经知道了,事务说白了就是一个词----统 ...
随机推荐
- 使用python和pygame绘制繁花曲线
前段时间看了一期<最强大脑>,里面展示了各种繁花曲线组合成的非常美丽的图形,一时心血来潮,想尝试自己用代码绘制繁花曲线,想怎么组合就怎么组合. 真实的繁花曲线使用一种称为繁花曲线规的小玩意 ...
- RPC原理解析
1.RPC原理解析 1.1 什么是RPC RPC(Remote Procedure Call Protocol) --远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络 ...
- 《统计学习方法》P89页IIS的中间步骤Zw+δ(X)/Zw(X)的推导
共有两个方法:
- 2017-2018-1 Java演绎法 小组成员贡献量汇总
[第一周]贡献量(31) [说明] 完成情况 是指 每次是否全部完成分配的任务,如果全部完成贡献量记为1,否则记为0,与贡献量(时间量)相加计算贡献比例,由于前十周有具体的任务分配,Alpha阶段(第 ...
- B-day5
1.昨天的困难,今天解决的进度,以及明天要做的事情 昨天的困难:昨天虽然完成了风险数据的图表统计,但是界面风格仍然不太满意,还在抓紧调试中:还有登录页的背景图,在想应该如何设计, 什么样的风格才好. ...
- 201621123062《java程序设计》第四周作业总结
1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 关键词:重载.继承.多态.static.final.抽象类 1.2 尝试使用思维导图将这些关键词组织起来.注:思维导图一般不需要 ...
- Alpha冲刺Day1
项目Alpha冲刺Day1 一.站立式会议 照片: 今日安排: 今天是项目开始的第一天,我们小组一起开会讨论了一下具体每天代码进度的落实情况,做了一下大体的规划.另外准备搭建一下环境和项目部署. 二. ...
- 【Swift】iOS导航栏错乱的原因
#iOS开发高级技巧#导航栏错乱,也就是导航栏的显示效果与内容区不匹配,引发原因很多,其中最重要的有两个原因: 1.在viewwillappear,viewwilldisappear两个函数中,设置导 ...
- equalsignorecase 和equals的区别
equals方法来自于Object类equalsIgnoreCase方法来自String类equals对象参数是Object 用于比较两个对象是否相等equals在Object类中方法默然比较对象内存 ...
- 利用flask 实现简单模版站
from flask import Flask,render_template from flask import request app = Flask(__name__) @app.route(' ...