当前位置: 首页 > news >正文

九亭做网站友情链接你会回来感谢我

九亭做网站,友情链接你会回来感谢我,企业做网站的步骤与做网站注意事项,做网站放什么软件文章目录概述1. 什么是spring的事务2. 两种使用事务的方式2.1 编程式事务管理2.2 声明式事务管理3. 事务的原理4. Spring 事务的传播属性4.1 什么是默认事务传播类型4.2 什么是事务挂起4.3 PROPAGATION_NESTED详解4.4 声明式事务的陷阱5. 数据库隔离级别与Spring中的隔离级别5.…

文章目录

  • 概述
  • 1. 什么是spring的事务
  • 2. 两种使用事务的方式
    • 2.1 编程式事务管理
    • 2.2 声明式事务管理
  • 3. 事务的原理
  • 4. Spring 事务的传播属性
    • 4.1 什么是默认事务传播类型
    • 4.2 什么是事务挂起
    • 4.3 PROPAGATION_NESTED详解
    • 4.4 声明式事务的陷阱
  • 5. 数据库隔离级别与Spring中的隔离级别
    • 5.1 数据库隔离级别
    • 5.2 Spring中的隔离级别
    • 5.3 注意事项
  • 参考

相关文章
spring 的事务(transaction) 一 基础概念介绍
spring 的事务(transaction) 二 陷阱
spring 的事务(transaction) 三 try catch对事务的影响
spring 的事务(transaction) 四 嵌套事务PROPAGATION_NESTED

概述

spring事务的原理是什么?

  • 首先mysql这样的数据库本身是支持事务的,有不同的事务隔离级别,事务分为手动开启事务和自动开启事务,参见 【mysql】MYSQL事务的开启与提交命令答疑,通过底层的支持,可以实现多条sql 原子化,要么都执行,要么都不执行
  • spring事务采用注解生成代理对象,把默认的自动开启事务变为手动开启,这样 多条sql语句都执行完后,才会提交事务

1. 什么是spring的事务

Spring事务 的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行:

事务这个概念是数据库层面的,Spring只是基于数据库中的事务进行了扩展,以及提供了一些能让程序员更加方便操作事务的方式。

    1. 获取连接 Connection con = DriverManager.getConnection()2. 开启事务con.setAutoCommit(true/false);3. 执行CRUD4. 提交事务/回滚事务 con.commit() / con.rollback();5. 关闭连接 conn.close();

使用Spring的事务管理功能后,我们可以不再写步骤 2 和 4 的代码,而是由Spirng 自动完成。

那么Spring是如何在我们书写的 CRUD 之前和之后开启事务和关闭事务的呢?解决这个问题,也就可以从整体上理解Spring的事务管理实现原理了。下面简单地介绍下,注解方式为例子:

配置文件开启注解驱动,在相关的类和方法上通过注解@Transactional标识。

spring 在启动的时候会去解析生成相关的bean,这时候会查看拥有相关注解的类和方法,并且为这些类和方法生成代理,并根据@Transaction的相关参数进行相关配置注入,这样就在代理中为我们把相关的事务处理掉了(开启正常提交事务,异常回滚事务)。

spring事务的实现可以当做是springAOP和IOC的结合使用。设计原理就是使用AOP实现了声明式事务处理的interceptor,封装了对spring的处理过程。

真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。

2. 两种使用事务的方式

在使用Spring框架时,可以有两种使用事务的方式,一种是编程式的,一种是声明式的,
@Transactional注解就是声明式的。

显然声明式事务管理要优于编程式事务管理,这正是Spring倡导的非侵入式的编程方式。唯一不足的地方就是声明式事务管理的粒度是方法级别,而编程式事务管理是可以到代码块的,但是可以通过提取方法的方式完成声明式事务管理的配置。

2.1 编程式事务管理

编程式事务管理是侵入性事务管理,使用TransactionTemplate或者直接使用PlatformTransactionManager,对于编程式事务管理,Spring推荐使用TransactionTemplate。

2.2 声明式事务管理

声明式事务也分为多种具体的种类,比如xml配置、注解元数据驱动(@Transactional注解)

声明式事务管理建立在AOP之上,其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,执行完目标方法之后根据执行的情况提交或者回滚。
编程式事务每次实现都要单独实现,但业务量大功能复杂时,使用编程式事务无疑是痛苦的,而声明式事务不同,声明式事务属于无侵入式,不会影响业务逻辑的实现,只需要在配置文件中做相关的事务规则声明或者通过注解的方式,便可以将事务规则应用到业务逻辑中。

3. 事务的原理

spring事务的实现可以当做是springAOP和IOC的结合使用。设计原理就是使用AOP实现了声明式事务处理的interceptor,封装了对spring的处理过程。

声明式事务实现首先需要配置aop环境,生成代理对象TransactionProxy和TrasactionInterceptor。封装不同的事务处理,整合具体实现到AOP和IOC。提供了即开即用的事务服务功能。在事务处理过程中,TransactionInfo和TransactionStatus是事务处理信息和状态的数据存储的对象。后面的事务处理都需要根据状态来进行的,当做参数传入。具体的事务处理是交给TransactionManager管理的,他提供了通用的事务处理模板,如doCommit等。具体的操作由具体的事务处理器来实现。

在一个方法上加了@Transactional注解后,Spring会基于这个类生成一个代理对象,会将这个代理对象作为bean,当在使用这个代理对象的方法时,如果这个方法上存在@Transactional注解,那么代理逻辑会先把事务的自动提交设置为false,然后再去执行原本的业务逻辑方法,如果执行业务逻辑方法没有出现异常,那么代理逻辑中就会将事务进行提交,如果执行业务逻辑方法出现了异常,那么则会将事务进行回滚。

当然,针对哪些异常回滚事务是可以配置的,可以利用@Transactional注解中的rollbackFor属性进行配置,默认情况下会对RuntimeException和Error进行回滚。

4. Spring 事务的传播属性

事务的传播性一般用在事务嵌套的场景,比如一个事务方法里面调用了另外一个事务方法,那么两个方法是各自作为独立的方法提交还是内层的事务合并到外层的事务一起提交,这就是需要事务传播机制的配置来确定怎么样执行。

这些属性在TransactionDefinition中定义,常用的事务传播机制如下:

  • PROPAGATION_REQUIRED
    Spring默认的传播机制,能满足绝大部分业务需求,如果外层有事务,则当前事务加入到外层事务,一块提交,一块回滚。如果外层没有事务,新建一个事务执行

  • PROPAGATION_REQUES_NEW
    该事务传播机制是每次都会新开启一个事务,同时把外层事务挂起,当当前事务执行完毕,恢复上层事务的执行。如果外层没有事务,执行当前新开启的事务即可

  • PROPAGATION_SUPPORT
    如果外层有事务,则加入外层事务,如果外层没有事务,则直接使用非事务方式执行。完全依赖外层的事务

  • PROPAGATION_NOT_SUPPORT
    该传播机制不支持事务,如果外层存在事务则挂起,执行完当前代码,则恢复外层事务,无论是否异常都不会回滚当前的代码

  • PROPAGATION_NEVER
    该传播机制不支持外层事务,即如果外层有事务就抛出异常

  • PROPAGATION_MANDATORY
    与NEVER相反,如果外层没有事务,则抛出异常

  • PROPAGATION_NESTED
    嵌套事务呈现父子事务概念,二者之间是有关联的,核心思想就是子事务不会独立提交,而是取决于父事务,当父事务提交,那么子事务才会随之提交;如果父事务回滚,那么子事务也回滚。

    但是子事务又有自己的特性,那 就是可以独立进行回滚,不会引发父事务整体的回滚(当然需要try catch子事务,避免异常传递至父层事务,如果没有,则也会引发腐父事务整体回滚)。这个特性比较有意思,虽然不能独立提交,但是可以独立回滚,因此,如果存在ABC 三个子事务,那么每个子事务都可以独立回滚,子事务类似一个游戏中的保存点,假设某个时间点,创建了一个保存点A,角色有10发子弹,主线继续发生时,对应执行某个子事务内的逻辑,如果游戏角色打了4发子弹,剩余6发子弹时挂了,点击返回上一个保存点,可以重新玩一次,此时该角色又是10发子弹,对应的就是子事务发生异常,子事务回滚到事务执行之前的那个点,放佛从来没有执行过该子事务一样,数据库的数据也不会发生变更。

    该传播机制的特点是可以保存状态保存点,当前事务回滚到某一个点,从而避免所有的嵌套事务都回滚,即各自回滚各自的,如果子事务没有把异常吃掉,基本还是会引起全部回滚的。

传播规则回答了这样一个问题:一个新的事务应该被启动还是被挂起,或者是一个方法是否应该在事务性上下文中运行。

常用的:

                PROPAGATION_REQUIRED PROPAGATION_REQUIRES_NEWPROPAGATION_NESTED

4.1 什么是默认事务传播类型

要注意默认事务传播类型和未设置事务的区别。

默认事务传播的前提是指通过配置或编码,引入事务,如果没有指定事务的传播类型,此时默认的事务传播类型为PROPAGATION_REQUIRED。

而未设置事务,就是没有事务。

4.2 什么是事务挂起

为了方便理解,我们把独立的2个事务,称之为外层事务和里面事务,如果2个事务相关,比如下文的PROPAGATION_NESTED ,此时可以称之为父子事务,表示关系更密切。

事务挂起一般是在出现独立事务的场景,即类似下面,外层和里层都有事务定义:

ServiceA {  /** * 事务属性配置为 PROPAGATION_REQUIRED */  void methodA() {  dosomethingBefore();ServiceB.methodB();  dosomethingAfter();}  }  ServiceB {  /** * 事务属性配置为 PROPAGATION_REQUES_NEW*/   void methodB() {  }  } 

注意我们上面代码中的是 2个不同的Service,而不是同一个service里面的2个不同方法,这涉及到陷阱问题,下文我们会讲。

ServiceA 的methodA()是外层事务,而ServiceB 的methodB()内会开启一个内层事务,此时这个内层事务是独立的,你可以把他理解成是个私密的空间,和外层互不干扰。可以理解成外层事务看不见内层事务,对于外层事务来说,甚至压根就不知道该内层事务的存在,当代码执行到内层事务时,外层事务就睡觉了(这就是挂起),当内层事务执行完,外层事务醒来,接着执行其余逻辑,好像对外层事务来说,什么多余的事情也没发生。

4.3 PROPAGATION_NESTED详解

PROPAGATION_NESTED 和PROPAGATION_REQUIRES_NEW的区别:

在这里插入图片描述

从上面可以看出,PROPAGATION_REQUIRES_NEW是平级关系,兄弟关系,二者之间没有关联;而PROPAGATION_NESTED 是类似父子关系。

有关更详细的信息,参见 spring 的事务(transaction) 四 嵌套事务PROPAGATION_NESTED

4.4 声明式事务的陷阱

5. 数据库隔离级别与Spring中的隔离级别

5.1 数据库隔离级别

隔离级别              隔离级别的值   导致的问题
Read-Uncommitted         0     		导致脏读
Read-Committed           1     		避免脏读,允许不可重复读和幻读
Repeatable-Read      	 2     		避免脏读,不可重复读,允许幻读
Serializable    		 3     		串行化读,事务只能一个一个执行,避免了脏读、不可重复读、幻读。执行效率慢,使用时慎重
  • 脏读:一事务对数据进行了增删改,但未提交,另一事务可以读取到未提交的数据。如果第一个事务这时候回滚了,那么第二个事务就读到了脏数据。
    不可重复读:一个事务中发生了两次读操作,第一次读操作和第二次操作之间,另外一个事务对数据进行了修改,这时候两次读取的数据是不一致的。
  • 幻读:第一个事务对一定范围的数据进行批量修改,第二个事务在这个范围增加一条数据,这时候第一个事务就会丢失对新增数据的修改。

总结:

  • 隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。
  • 大多数的数据库默认隔离级别为 Read Commited,比如 SqlServer、Oracle
  • 少数数据库默认隔离级别为:Repeatable Read 比如: MySQL InnoDB

5.2 Spring中的隔离级别

常量                            解释
ISOLATION_DEFAULT             这是个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别。另外四个与 JDBC 的隔离级别相对应。
ISOLATION_READ_UNCOMMITTED    这是事务最低的隔离级别,它充许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。
ISOLATION_READ_COMMITTED      保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。
ISOLATION_REPEATABLE_READ     这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。
ISOLATION_SERIALIZABLE        这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。

5.3 注意事项

数据库的配置隔离级别是Read Commited,而Spring配置的隔离级别是Repeatable Read,请问这时隔离级别是以哪一个为准?

以Spring配置的为准,如果spring设置的隔离级别数据库不支持,效果取决于数据库。

参考

【Spring 核心】(4):Spring事务 的实现
有关Spring事务,看这一篇就足够了
事务之六:spring 嵌套事务 列出多个样例
嵌套事务总结 更多的例子

http://www.lbrq.cn/news/2468791.html

相关文章:

  • wordpress多用户商城系统上海整站seo
  • 如何通过网站做网上报名系统seo技术推广
  • 杭州战争网站建设投资网站建设方案
  • 做网站精英软文写作服务
  • p2p网站制作价格专业网站建设
  • 域名没备案如何建设网站台州关键词优化服务
  • 重庆网上房地产查询备案价裤子seo关键词
  • 给网站可以怎么做外链nba最新排名
  • 搜索引擎网站推广可以自己做吗网站推广的工作内容
  • 政府网站建设项目简介凤凰网台湾资讯
  • 网页在线代理上网网站自然优化
  • 做阿里还是网站最近中国新闻热点大事件
  • 男人和女人做受吃母乳视频网站免费福建优化seo
  • 事业单位网站模板网页设计自学要多久
  • 做网站开发用sublime好吗seo搜索引擎优化原理
  • 网站网页设计招聘上海关键词优化推荐
  • 辽宁省建设厅网站升级拓客app下载
  • 热水工程技术支持 东莞网站建设宁波关键词网站排名
  • 山西自助建站费用低品牌营销的概念
  • 南京企业自助建站系统安卓手机优化软件哪个好
  • 商城模板建站价格营销模式有几种
  • 曲靖网站建设搜索引擎优化seo公司
  • 券优惠网站如何做竞价推广方案
  • 实战营销型网站建设网络流量统计工具
  • 建设厅网站查询资质营销策划的八个步骤
  • 怎样可以查到做网站公司个人接外包项目平台
  • 桂林北站改造seo的英文全称是什么
  • php网站挂到linux服务器上应该这么做网络优化工程师有多累
  • 长春建站价格重庆整站seo
  • 做网站的大小百度代运营
  • C++中new和delete的多重面孔:operator new、new operator与placement new解析
  • MCP 与传统集成方案深度对决:REST API、GraphQL、gRPC 全方位技术解析
  • Gitee Test:国产软件测试平台如何筑牢关键领域数字安全屏障
  • vscode 字体的跟换
  • rust-方法语法
  • SQL基础⑪ | 约束