当前位置: 首页 > 编程笔记 >

简单了解Spring中的事务控制

艾飞宇
2023-03-14
本文向大家介绍简单了解Spring中的事务控制,包括了简单了解Spring中的事务控制的使用技巧和注意事项,需要的朋友参考一下

1.事务的概念

事务是一组操作的执行单元,相对于数据库的单条操作而言,事务管理的是一组SQL指令,如增删改查等,事务的特性体现在事务内包含的SQL指令必须全部执行成功,如果其中一条指令发生错误,那么整个事务内的一组操作都要进行回滚。

事务有四个特性:

  • 原子性 Atomic ,事务是一个不可再拆分的最小单位,要么整个执行,要么整个回滚.
  • 一致性 Consistent,事务要保证数据库整体数据的完整性和业务的数据的一致性,事务成功提交整体数据修改,事务错误则回滚到数据回到原来的状态。
  • 隔离性 Isolate,两个事务的执行都是独立的,事务之前不会相互影响,多个事务操作一个对象时会以串行等待的方式保证事务相互之间处于隔离。
  • 持久性 Durable,一旦事务成功提交后,数据将会保存到数据库,不能再进行回滚,以后的操作都将在当前数据库状态上继续进行。

2.Spring中的事务控制方式

编程式事务管理

通过手动编码控制事务的边界,可以实现细粒度的事务控制,一般用的较少。

声明式事务管理

只需要在Spring中添加一些配置文件或者使用注解,即可实现将操作纳入事务管理中,事务管理使用了Spring AOP,降低了代码之间的耦合。

3.事务管理器

Spring中并没有直接管理事务,而是将管理事务委托给相应的持久化机制提供的某个特定平台的实现。

事务管理器实现 目标
org.springframework.jdbc.datasource.DataSourceTransactionManager 在单一的JDBC Datasource中管理事务
org.springframework.orm.hibernate5.HibernateTransactionManager 当持久化机制是hibernate时,用它来管理事务
org.springframework.jdo.JdoTransactionManager 当持久化机制是Jdo时,用它来管理事务
org.springframework.transaction.jta.JtaTransactionManager 使用一个JTA实现来管理事务。在一个事务跨越多个资源时必须使用
org.springframework.orm.ojb.PersistenceBrokerTransactionManager 当apache的ojb用作持久化机制时,用它来管理事务

4.事务属性简介

Spring关于事务的注解中有以下几个属性(部分)

@Transactional(
readOnly = false, //读写事务
timeout = -1, //超时
noRollbackFor = ArithmeticException.class //遇到数学异常不回滚
isolation = Isolation.REPEATABLE_READ, //事务隔离级别
propagation = Propagation.REQUIRED //事务传播规则
)
  • 是否为只读事务:只读事务不做任何修改,可以优化查询操作。
  • 事务超时(单位为秒):事务的最长持续时间,如果该时间内事务一直没有操作或回滚,则系统将自动进行回滚。-1表示不超时,但最终实现需要由底层数据库实现。
  • 隔离级别:控制并发访问下数据库的安全性。
  • 传播规则:定义事务方法和调用事务方法的方法之间的事务边界。

5.事务传播规则

传播行为 意义
REQUIRED 业务方法需要在一个事务中运行。如果方法运行时,已经处在一个事务中,那么加入到该事务,否则为自己创建一个新的事务
NOT_SUPPORTED 声明方法不需要事务。如果方法没有关联到一个事务,容器不会为它开启事务。如果方法在一个事务中被调用,该事务会被挂起,在方法调用结束后,原先的事务便会恢复执行
REQUIRES_NEW 属性表明不管是否存在事务,业务方法总会为自己发起一个新的事务。如果方法已经运行在一个事务中,则原有事务会被挂起,新的事务会被创建,直到方法执行结束,新事务才算结束,原先的事务才会恢复执行
MANDATORY 该属性指定业务方法只能在一个已经存在的事务中执行,业务方法不能发起自己的事务。如果业务方法在没有事务的环境下调用,容器就会抛出异常
SUPPORTS 这一事务属性表明,如果业务方法在某个事务范围内被调用,则方法成为该事务的一部分。如果业务方法在事务范围外被调用,则方法在没有事务的环境下执行
NEVER 指定业务方法绝对不能在事务范围内执行。如果业务方法在某个事务中执行,容器会抛出异常,只有业务方法没有关联到任何事务,才能正常执行
NESTED 如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按REQUIRED属性执行.它使用了一个单独的事务, 这个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效

6.事务隔离级别

隔离级别 意义
DEFAULT 默认的隔离级别
READ_UNCOMMITED 允许你读取还未提交的改变了的数据。可能导致脏、幻、不可重复读
READ_COMMITTED 允许在并发事务已经提交后读取。可防止脏读,但幻读和 不可重复读仍可发生
REPEATABLE_READ 对相同字段的多次读取是一致的,除非数据被事务本身改变。可防止脏、不可重复读,但幻读仍可能发生
SERIALIZABLE 完全服从事务ACID的隔离级别,确保不发生脏、幻、不可重复读。这在所有的隔离级别中是最慢的,它是典型的通过完全锁定在事务中涉及的数据表来完成的

  • 不同的隔离级别采用不同的方式来实现,在四种隔离级别中,Serializable的隔离级别最高,Read Uncommited的隔离级别最低。
  • 大多数据库默认的隔离级别为Read Commited,如SqlServer,Oracle
  • 当然也有少部分数据库默认的隔离级别为Repeatable_Read ,如Mysql,
  • Oracle数据库支持READ COMMITTED和SERIALIZABLE两种事务隔离性级别,不支持READ UNCOMMITTED和REPEATABLE READ这两种隔离性级别。虽然SQL标准定义的默认事务隔离性级别是SERIALIZABLE,但是Oracle数据库默认使用的事务隔离性级别却是READ COMMITTED.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 问题内容: 我正在尝试通过以下示例来消除我对Spring Transaction边界的怀疑。 我想将test2()方法与test1()隔离开,即每次调用test()时,test2()都不应读取test1()提交的数据。请建议是否可以使用传播或隔离属性来处理这种情况。 提前致谢。 问题答案: 事务属性应用于外部调用,而不是由bean方法(例如您的案例)进行的内部调用。如果要将事务边界应用于调用,则应

  • 本文向大家介绍简单了解Spring中BeanFactory与FactoryBean的区别,包括了简单了解Spring中BeanFactory与FactoryBean的区别的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了简单了解Spring中BeanFactory与FactoryBean的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考

  • 本文向大家介绍Spring事务事件监控的实现,包括了Spring事务事件监控的实现的使用技巧和注意事项,需要的朋友参考一下 前面我们讲到了Spring在进行事务逻辑织入的时候,无论是事务开始,提交或者回滚,都会触发相应的事务事件。本文首先会使用实例进行讲解Spring事务事件是如何使用的,然后会讲解这种使用方式的实现原理。 1.示例 对于事务事件,Spring提供了一个注解@Transaction

  • 问题内容: 在PHP文件说: 如果您以前从未遇到过事务,则它们提供4个主要功能:原子性,一致性,隔离性和持久性(ACID)。用外行的术语来说,事务中执行的任何工作,即使它是分阶段进行的,都可以保证在提交时安全地应用于数据库,并且不受其他连接的干扰。 题: 这是否意味着我可以让两个单独的php脚本同时运行事务,而又彼此不干扰? 通过 “ 干扰 ” 细化我的 意思 : 假设我们有下表: 如果我有两个脚

  • 问题内容: JOIN和在FROM子句中声明多个表有什么区别? 如: 相比: 问题答案: 第二个版本具有显式和联接条件,是标准化的SQL。 带有子句的隐式连接语法是不赞成使用的语法(或者,被认为是不好的)-部分原因是很容易忘记该子句并导致笛卡尔积。

  • 本文向大家介绍简单了解Spring Cloud Alibaba相关知识,包括了简单了解Spring Cloud Alibaba相关知识的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了简单了解Spring Cloud Alibaba相关知识,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 官方github地址 Spring Cloud A