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的事务 首先,大家已经知道了,事务说白了就是一个词----统 ...
随机推荐
- linux新建用户登录不了
useradd----创建用户命令 简单的创建普通用户(当然得在root登录下执行) useradd username -p password userdel username 删除用户 用上面的命令 ...
- java实现循环链表的增删功能
java实现循环链表的增删功能,完整代码 package songyan.test.demo; public class Demo { // java 实现循环链表 public static voi ...
- Redis的事务和watch
redis的事务 严格意义来讲,redis的事务和我们理解的传统数据库(如mysql)的事务是不一样的. redis中的事务定义 Redis中的事务(transaction)是一组命令的集合. 事务同 ...
- 大数据 --> Kafka集群搭建
Kafka集群搭建 下面是以三台机器搭建为例,(扩展到4台以上一样,修改下配置文件即可) 1.下载kafka http://apache.fayea.com/kafka/0.9.0.1/ ,拷贝到三台 ...
- Hibernate——配置并访问数据库
Hibernate,对于java来说很重要的一个东西,用于持久层.之前看了很多配置的,都不行,自己来写一个配置成功的. 环境:jdk1.8,eclipse-jee-oxygen,mysql-conne ...
- 启动django应用报错 “Error: [WinError 10013] 以一种访问权限不允许的方式做了一个访问套接字的尝试。”
启动django应用时报如下错误 "Error: [WinError 10013] 以一种访问权限不允许的方式做了一个访问套接字的尝试." 网上查了一下,是8000端口被其他程序占 ...
- logging日志
import logging logging.basicConfig(filename='log.log', format='%(asctime)s - %(name)s - %(levelname) ...
- Flask 学习 八 用户角色
角色在数据库中表示 app/models.py class Role(db.Model): __tablename__='roles' id = db.Column(db.Integer,primar ...
- 从PRISM开始学WPF(二)Prism?
目录: 从PRISM开始学WPF(一)WPF? 从PRISM开始学WPF(二)Prism? 从PRISM开始学WPF(三)Prism-Region? 从PRISM开始学WPF(四)Prism-Modu ...
- PC或者手机弹出窗效果
http://layer.layui.com/ 这个网站提供弹窗,是在jq封装的,弹窗之后,背景页面还可以滑动. 这个里面的js可能也会包含css,这个css不能移动位置,否则会报错,还有谷歌浏览器在 ...