对事务的复习

什么是事务:

  • 事务(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 对事务的整合的更多相关文章

  1. Spring事务管理----------整合学习版

    作者:学无先后 达者为先 Spring提供了一流的事务管理.在Spring中可以支持声明式事务和编程式事务. 一  spring简介 1 Spring的事务       事务管理在应用程序中起着至关重 ...

  2. Mybatis整合Spring实现事务管理的源码分析

    一:前言 没有完整看完,但是看到了一些关键的地方,这里做个记录,过程会有点乱,以后逐渐补充最终归档为完整流程:相信看过框架源码的都知道过程中无法完全确定是怎样的流程,毕竟不可能全部都去测试一遍 ,但是 ...

  3. 【spring 7】spring和Hibernate的整合:声明式事务

    一.声明式事务简介 Spring 的声明式事务管理在底层是建立在 AOP 的基础之上的.其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者 ...

  4. 如何实现XA式、非XA式Spring分布式事务

    Spring应用的几种事务处理机制 Java Transaction API和XA协议是Spring常用的分布式事务机制,不过你可以选择选择其他的实现方式.理想的实现取决于你的应用程序使用何种资源,你 ...

  5. 非XA式Spring分布式事务

    Spring应用的几种事务处理机制 Java Transaction API和XA协议是Spring常用的分布式事务机制,不过你可以选择选择其他的实现方式.理想的实现取决于你的应用程序使用何种资源,你 ...

  6. 基于maven进行spring 和mybatis的整合(Myeclpise)

    学习日记:基于maven进行spring和mybatis的整合,进行分页查询 什么是maven:maven是一个项目管理工具,使用maven可以自动管理java项目的整个生命周期,包括编译.构建.测试 ...

  7. Spring+SpringMVC+MyBatis+easyUI整合优化篇(四)单元测试实例

    日常啰嗦 前一篇文章<Spring+SpringMVC+MyBatis+easyUI整合优化篇(三)代码测试>讲了不为和不能两个状态,针对不为,只能自己调整心态了,而对于不能,本文会结合一 ...

  8. Spring+SpringMVC+MyBatis+easyUI整合优化篇(十三)数据层优化-表规范、索引优化

    本文提要 最近写的几篇文章都是关于数据层优化方面的,这几天也在想还有哪些地方可以优化改进,结合日志和项目代码发现,关于数据层的优化,还是有几个方面可以继续修改的,代码方面,整合了druid数据源也开启 ...

  9. spring和hibernate的整合

    阅读目录 一.概述 二.整合步骤 1.大致步骤 2.具体分析 一.概述 Spring整合Hibernate有什么好处? 1.由IOC容器来管理Hibernate的SessionFactory 2.让H ...

随机推荐

  1. vue项目过程的理解: main.js文件理解 router.js文件理解 以及组件 路由 等之间的关系

    https://blog.csdn.net/qq_26229005/article/details/85040393 内容太多了,有空再整理

  2. PB笔记之数据窗口大小自适应的方式

    1.在OPEN 事件中设置数据窗口大小属性 tab_1.tabpage_6.dw_6.x=0tab_1.tabpage_6.dw_6.y=0tab_1.tabpage_6.dw_6.width=thi ...

  3. hdu 6562 Lovers (线段树)

    大意: 有$n$个数字串, 初始为空, 两种操作(1)把$[l,r]$范围的所有数字串首位添加数位$d$ (2)询问$[l,r]$区间和 假设添加的数为$L$, $L$位数为$H$, $L$翻转后乘上 ...

  4. 转:common.js 常用js公共函数库

    转自其他博主,自己开发备用 var h = {}; h.get = function (url, data, ok, error) { $.ajax({ url: url, data: data, d ...

  5. iOS - 性能优化:Instruments使用简介

    最近采用Instruments 来分析整个应用程序的性能.发现很多有意思的点,以及性能优化和一些分析性能消耗的技巧,小结如下. Instruments使用技巧 关于Instruments官方有一个很有 ...

  6. jQuery 事件介绍

    什么是事件?页面对不同访问者的响应叫做事件.事件处理程序指的是当 HTML 中发生某些事件时所调用的方法. 常用的时间主要有以下几种: click()事件:click() 方法是当按钮点击事件被触发时 ...

  7. Hbuilder中配置cmd

    步骤: 1. ①运行——>外部工具——>外部工具 配置2.  新建一个名为cmd(随意命名)的外部工具: 名称:cmd 要执行的命令或文件:C:\Windows\System32\cmd. ...

  8. UI5-技术篇-事务Tcode

    1.LPD_CUST 快速启动板概览 2./N/UI2/FLPD_CONF 创建目录与组(全部客户端) 3./N/UI2/FLPD_CUST 创建目录与组(当前客户端) 4./N/UI2/FLP 编辑 ...

  9. pycharm git 用法总结

    一.配置git 二.登录GitHub账号 三.创建git respository 四.提交文件 五.共享给GitHub 六.修改文件push到版本库 七.从版本库checkout 项目

  10. SQLSEVER在存储过程或触发器中模糊查询拼接

    declare @name nvarchar(50); declare @name_pin nvarchar(50); set @name_pin = '%'+@name +'%' 模糊查询: sel ...