Spring 对事务的整合
对事务的复习
什么是事务:
- 事务(TRANSACTION) 是作为单个逻辑工作单元执行的一系列操作。
- 多个操作作为一个整体向系统提交,要么都执行,要么都不执行。
- 事务是一个不可分割的逻辑单元。
事务的特性:
事务具备以下四个特性,简称ACID属性。
l 原子性(Atomicity):
事务是一个完整的操作,事务的各步操作都是不可再分的,要么都执行, 要么都不执行。
l 一致性(Consistency):
当事务完成时,数据必须处于一致的状态。
l 隔离性(Isolation):
并发事务之间相互独立、隔离,它不应以任何方式依赖于或影响其他事 务。
l 持久性(Durability):
事务完成后,它对数据库的修改被永久保持。
10.2Spring中对事务的整合
在Spring中,所有操作事务的类都继承自 PlatformTransactionManager
事务的隔离级别

- ISOLATION_READ_UNCOMMITTED:读未提交
- ISOLATION_READ_COMMITTED:读已提交
- ISOLATION_REPEATABLE_READ:可重复读
- ISOLATION_SERIALIZABLE:串行化
脏读、不可重复读、幻读
脏读:A事务读取B事务尚未提交的更改数据,并在这个数据的基础上进行操作,这时候如果事务B回滚,那么A事务读到的数据是不被承认的。例如常见的取款事务和转账事务:

不可重复读:不可重复读是指A事务读取了B事务已经提交的更改数据。假如A在取款事务的过程中,B往该账户转账100,A两次读取的余额发生不一致。
幻读:A事务读取B事务提交的新增数据,会引发幻读问题。幻读一般发生在计算统计数据的事务中,例如银行系统在同一个事务中两次统计存款账户的总金额,在两次统计中,刚好新增了一个存款账户,存入了100,这时候两次统计的总金额不一致。

事务的七种传播行为
什么是事务的传播行为:事务传播行为用来描述由某一个事务传播行为修饰的方法被嵌套进另一个方法的时事务如何传播。

案例一:转账
结构如下:

首先先创建entity与Dao与DaoImpl
public interface IBankDao {
//转出
int RolloutMoney(String code_crde,String code_money);
//转入
int RollinMoney(String code_crde,String code_money);
}
@Repository
public class IBankDaoImpl implements IBankDao {
@Resource
private JdbcTemplate jdbcTemplate;
@Override
public int RolloutMoney(String code_crde, String code_money) {
int outcount = jdbcTemplate.update("update bank set code_money=code_money-? where code_crde=?", code_money, code_crde);
return outcount;
} @Override
public int RollinMoney(String code_crde, String code_money) {
int incount = jdbcTemplate.update("update bank set code_money=code_money+? where code_crde=?", code_money, code_crde);
return incount;
}
}
public class Bank {
private String code_crde;
private String code_name;
private String code_money;
创建Service与impl
public interface IBankServce {
int transfer(String out_code_crde,String in_code_crde,String money) throws Exception;
}
@Service("iBankServce")
public class IBankServiceImpl implements IBankServce {
@Resource
private IBankDao iBankDao;
@Override
public int transfer(String out_code_crde, String in_code_crde, String money) {
int outcount = iBankDao.RolloutMoney(out_code_crde, money);
if (true){
throw new RuntimeException("异常");
}
int incount = iBankDao.RollinMoney(in_code_crde, money);
return outcount+incount;
}
}
编写text
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-day19jdbcZHUJIE.xml");
IBankServce iBankServce = (IBankServce)ctx.getBean("transactionProxy");
int transfer = 0;
try {
transfer = iBankServce.transfer("987654321", "1234568479", "100");
} catch (Exception e) {
e.printStackTrace();
}
if (transfer>0){
System.out.println("cg");
}
}
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="cn.bank"></context:component-scan>
<!--2.识别到配置文件-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--1.配置数据源-->
<!--Spring内置的内置源:创建或者用来提供连接的,不负责管理,使用连接池-->
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--3.构建jdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="datasource"></property>
</bean>
<!--事物管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--管理数据-->
<property name="dataSource" ref="datasource"></property>
</bean>
<!--事物代理工厂Bean-->
<bean id="transactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!--事物管理器-->
<property name="transactionManager" ref="transactionManager"></property>
<!--目标对象-->
<property name="target" ref="iBankServce"></property>
<!--设置方法-->
<property name="transactionAttributes">
<props>
<!--方法对应的隔离以及传播行为-->
<prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT</prop>
</props>
</property>
</bean>
<aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>

如图所示,出现异常则直接回滚,数据库数据不变
Aop实现方式
<context:component-scan base-package="cn.bank"></context:component-scan>
<!--2.识别到配置文件-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--1.配置数据源-->
<!--Spring内置的内置源:创建或者用来提供连接的,不负责管理,使用连接池-->
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--3.构建jdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="datasource"></property>
</bean>
<!--事物管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--管理数据-->
<property name="dataSource" ref="datasource"></property>
</bean> <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="trans*" isolation="READ_COMMITTED" propagation="REQUIRED"></tx:method>
</tx:attributes>
</tx:advice> <aop:config>
<!--切点-->
<aop:pointcut id="poincut" expression="execution(* *..service.Impl.*.*(..))"/>
<aop:advisor advice-ref="transactionAdvice" pointcut-ref="poincut"></aop:advisor>
</aop:config> </beans>
注解实现方式
前置代码一样后置ServiceImpl如下:
@Service("iBankServce")
public class IBankServiceImpl implements IBankServce {
@Resource
private IBankDao iBankDao;
@Transactional(isolation = Isolation.REPEATABLE_READ,propagation = Propagation.REQUIRED)
@Override
public int transfer(String out_code_crde, String in_code_crde, String money) {
int outcount = iBankDao.RolloutMoney(out_code_crde, money);
if (true){
throw new RuntimeException("异常");
}
int incount = iBankDao.RollinMoney(in_code_crde, money);
return outcount+incount;
}
}
Xml文件进行注解的读取
<context:component-scan base-package="cn.bankzhu"></context:component-scan>
<!--2.识别到配置文件-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--1.配置数据源-->
<!--Spring内置的内置源:创建或者用来提供连接的,不负责管理,使用连接池-->
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--3.构建jdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="datasource"></property>
</bean>
<!--事物管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--管理数据-->
<property name="dataSource" ref="datasource"></property>
</bean>
<!--注解支持-->
<tx:annotation-driven/>
</beans>
Spring 对事务的整合的更多相关文章
- Spring事务管理----------整合学习版
作者:学无先后 达者为先 Spring提供了一流的事务管理.在Spring中可以支持声明式事务和编程式事务. 一 spring简介 1 Spring的事务 事务管理在应用程序中起着至关重 ...
- Mybatis整合Spring实现事务管理的源码分析
一:前言 没有完整看完,但是看到了一些关键的地方,这里做个记录,过程会有点乱,以后逐渐补充最终归档为完整流程:相信看过框架源码的都知道过程中无法完全确定是怎样的流程,毕竟不可能全部都去测试一遍 ,但是 ...
- 【spring 7】spring和Hibernate的整合:声明式事务
一.声明式事务简介 Spring 的声明式事务管理在底层是建立在 AOP 的基础之上的.其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者 ...
- 如何实现XA式、非XA式Spring分布式事务
Spring应用的几种事务处理机制 Java Transaction API和XA协议是Spring常用的分布式事务机制,不过你可以选择选择其他的实现方式.理想的实现取决于你的应用程序使用何种资源,你 ...
- 非XA式Spring分布式事务
Spring应用的几种事务处理机制 Java Transaction API和XA协议是Spring常用的分布式事务机制,不过你可以选择选择其他的实现方式.理想的实现取决于你的应用程序使用何种资源,你 ...
- 基于maven进行spring 和mybatis的整合(Myeclpise)
学习日记:基于maven进行spring和mybatis的整合,进行分页查询 什么是maven:maven是一个项目管理工具,使用maven可以自动管理java项目的整个生命周期,包括编译.构建.测试 ...
- Spring+SpringMVC+MyBatis+easyUI整合优化篇(四)单元测试实例
日常啰嗦 前一篇文章<Spring+SpringMVC+MyBatis+easyUI整合优化篇(三)代码测试>讲了不为和不能两个状态,针对不为,只能自己调整心态了,而对于不能,本文会结合一 ...
- Spring+SpringMVC+MyBatis+easyUI整合优化篇(十三)数据层优化-表规范、索引优化
本文提要 最近写的几篇文章都是关于数据层优化方面的,这几天也在想还有哪些地方可以优化改进,结合日志和项目代码发现,关于数据层的优化,还是有几个方面可以继续修改的,代码方面,整合了druid数据源也开启 ...
- spring和hibernate的整合
阅读目录 一.概述 二.整合步骤 1.大致步骤 2.具体分析 一.概述 Spring整合Hibernate有什么好处? 1.由IOC容器来管理Hibernate的SessionFactory 2.让H ...
随机推荐
- Python04之数据类型
Python的数据类型主要有四类:整型.浮点型.字符串类型.布尔类型 整型:所有整数都属于整型(长整型和整型) 如:-121,0,765,89,12306 浮点型:数字上有小数点的数 ...
- PAT(B) 1064 朋友数(Java)
题目链接:1064 朋友数 (20 point(s)) 题目描述 如果两个整数各位数字的和是一样的,则被称为是"朋友数",而那个公共的和就是它们的"朋友证号". ...
- 从C++到Qt(舍弃IDE或qmake、cmake等工具的束缚,尝试通过几个例子)
Qt 是 C++ 的库,Qt 在 ansi C++ 的基础上进行了一点扩展. 但国内似乎比较浮躁,学Qt的很多连基本的C++如何编译似乎都不太清楚.本文舍弃IDE或qmake.cmake等工具的束缚, ...
- jquery滚动到顶部
<script> $.fn.scrollTo = function (options) { var defaults = { toT: , //滚动目标位置 durTime: , //过渡 ...
- sprint boot websocket 服务端+html5 示例测试
包依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>sp ...
- javascript进度条实现
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- 测试人员必须掌握的linu常用命令
有些公司需要测试人员部署程序包,通过工具xshell. 现在我将总结下工作需要用到的最多的命令 ls 显示文件或目录 pwd ...
- jquery input file 多图上传,单张删除,查看
<div class="form-group"> <label for="imgs" class="col-md-3 col-sm- ...
- 文件锁 flock/fcntl
多个进程同时操作一个文件 1. flock int flock(int fd, int operation); LOCK_SH 建立共享锁定.多个进程可同时对同一个文件作共享锁定(读锁定) LOCK_ ...
- Android NDK 学习之在C中抛出异常
本博客主要是在Ubuntu 下开发,且默认你已经安装了Eclipse,Android SDK, Android NDK, CDT插件. 在Eclipse中添加配置NDK,路径如下Eclipse-> ...