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 ...
随机推荐
- 长乐培训Day6
T1 数列 题目 [题目描述] [输入格式] [输出格式] [输入样例] [输出样例] [数据规模] 如上所述. 解析 身为T1,居然比T4还难......让我怎么办......以下为巨佬题解: 我猜 ...
- try except 异常捕获的方法、断言的使用
except as e中的'e'的作用总结 - 2puT - CSDN博客 Python使用try except处理程序异常的三种常用方法分析 Python3和Python2 异常处理except的不 ...
- hdu 6185 递推+矩阵快速幂
思路:考虑全部铺满时,前2列的放法.有如下5种情况:(转自http://blog.csdn.net/elbadaernu/article/details/77825979 写的很详细 膜一下) 假设 ...
- .NET Standards
.net的创始者们在一开始的时候,就意识到了他们的编程技术可以用在不通的操作系统和不同类型的cpu上.他们改进了20世纪90年代编程语言实现技术.最主要的一条是,不同的编程语言对应统一个运行时,及CL ...
- kubernets 证书过期的问题
.问题起源 kubeadm 是 kubernetes 提供的一个初始化集群的工具,使用起来非常方便.但是它创建的apiserver.controller-manager等证书默认只有一年的有效期,同时 ...
- R_数据视觉化处理_初阶_02
通过数据创建一幅简单的图像, #Crate a easy photopdf("mygraph.pdf") attach(mtcars) plot(wt,mpg) abline(lm ...
- 后端参数校验器v1.0(调用一个方法校验所有参数并得到校验结果,且包括错误原因)
一:介绍 在写后端时,面对多个参数,比如手机号码.密码等我们常常需要写验证逻辑,当需要验证的参数较多的时候我们会需要写很多的判断语句,这就造成了大量的代码冗余.因此我开发了一套参数验证器,只需要调用参 ...
- 【转载】C#使用Split函数根据特定分隔符分割字符串
在C#程序开发过程中,很多时候可能需要将字符串根据特定的分割字符分割成字符或者List集合,例如根据逗号将字符串分割为数组,或者根据竖线将字符串分割成数组,C#中提供了Split()函数来快速将字符串 ...
- (详细)Eclips+jsp+servlet+mysql+登录实例+源代码
欢迎任何形式的转载,但请务必注明出处. 该教程较全,从软件的安装以及相关的环境配置我都放置了相关教程的链接,读者可直接点击进入.自己写电商网站作业时查找了很多资料,但都不是很全,所以趁着寒假写了这份教 ...
- Python 自己实现可迭代对象
import time from collections import Iterable from collections import Iterator class Classmate(object ...