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的事务 首先,大家已经知道了,事务说白了就是一个词----统 ...
随机推荐
- TPYBoard v102 DIY照相机(视频和制作流程)
前段时间的帖子,利用TPYBoard v102做的DIY照相机,周末实物终于做出来了,加了两个按键模块和一个5110,做的有点糙啊----望大家勿怪,哈哈哈.拍出来图片还算清晰,串口摄像头模块用的30 ...
- SpringBoot中MongoDB注解概念及使用
spring-data-mongodb主要有以下注解 @Id 主键,不可重复,自带索引,可以在定义的列名上标注,需要自己生成并维护不重复的约束.如果自己不设置@Id主键,mongo会自动生成一个唯一主 ...
- 【Python】 SSH连接的paramiko
paramiko *paramiko需要PyCrypto模块的支持 paramiko支持通过SSH协议进行一些操作,比如远程执行命令,上下传文件等等 用法: ① 远程命令 ssh = paramiko ...
- Algorithm --> 顺序打印矩阵
顺序打印矩阵 思路 参考代码 #include <iostream> using namespace std; ], int row, int col) { || col < ) r ...
- RxJS -- Subscription
Subscription是什么? 当subscribe一个observable的时候, 返回的就是一个subscription. 它是一个一次性对象(disposable), 它有一个非常重要的方法 ...
- apache实现301永久性重定向代码
301重定向(301 redirect)又叫301代表永久性转移(Permanently Moved),将各种网络请求重新定个方向转到其它位置,是网页更改地址后对搜索引擎友好的最好方法,只要不是暂时搬 ...
- Vue探索历程(一)
使用vue.js原文介绍:Vue.js是一个构建数据驱动的web界面库.Vue.js的目标是通过尽可能简单的API实现响应式数据绑定和组合的视图组件.vue.js上手非常简单,先看看几个例子: 例一: ...
- Struts2学习笔记二 配置详解
Struts2执行流程 1.简单执行流程,如下所示: 在浏览器输入请求地址,首先会被过滤器处理,然后查找主配置文件,然后根据地址栏中输入的/hello去每个package中查找为/hello的name ...
- alpha冲刺第三天
一.合照 二.项目燃尽图 三.项目进展 今天是一个瓶颈期,在昨天被困住的地方今天还是没能解决,所以今天的项目进展并没有发生什么变化. 今天晚上xl和lj去实验室找学姐了,在学姐的帮助下大概有了一点思路 ...
- C语言作业第二次总结
1.作业亮点 1.1作业整体概况 本次作业全体同学能够按时完成作业,且大部分同学的作业体现了自己的思路和方法,具备了一定变成能力. 1.2推荐博客 林岳-代码注释清晰,详细.->博文 王艺斌-算 ...