Spring事务及其注解

本文详细探讨了Spring框架中的事务管理,包括事务的本质、事务管理器、事务注解的使用和配置、事务的属性分析、传播特性、隔离级别、回滚规则等。还介绍了编程式和声明式事务的区别及实现过程,强调了声明式事务的优势。同时,文章讨论了事务与线程、会话的关系,以及如何保证事务连接的唯一性。
摘要由CSDN通过智能技术生成

Spring事务相关

Spring事务是Spring框架中的重要知识点,本文针对之前秋招的学习成果进行简单总结。内容有点多,另外关于AOP动态代理的内容估计会另外写篇文章来总结了,建议看完后自己重新总结印象会比较深刻。


Spring事务的本质

Spring事务的本质是数据库对事务的支持。


Spring和事务的关系

关系型数据库、某些消息队列等产品或中间件称为事务性资源,因为它们本身支持事务,也能够处理事务。
Spring很显然不是事务性资源,但是它可以管理事务性资源,所以Spring和事务之间是管理关系。


Spring事务三要素

数据源:表示具体的事务性资源,是事务的真正处理者,如MySQL等。

事务管理器:像一个大管家,从整体上管理事务的处理过程,如打开、提交、回滚等。

事务应用和属性配置:像一个标识符,表明哪些方法要参与事务,如何参与事务,以及一些相关属性如隔离级别、超时时间等。


Spring事务的注解配置

把一个DataSource(如DruidDataSource)作为一个@Bean注册到Spring容器中,配置好事务性资源。
把一个@EnableTransactionManagement注解放到一个@Configuration类上,配置好事务管理器,并启用事务管理。
把一个@Transactional注解放到类上或方法上,可以设置注解的属性,表明该方法按配置好的属性参与到事务中。


事务注解的本质

@Transactional这个注解仅仅是一些(和事务相关的)元数据,在运行时被事务基础设施读取消费,并使用这些元数据来配置bean的事务行为。
大致来说具有两方面功能,一是表明该方法要参与事务,二是配置相关属性来定制事务的参与方式和运行行为。


Spring事务的表达方式

spring支持编程式事务管理和声明式事务管理两种方式。

编程式事务 使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。

声明式事务 是建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。

显然声明式事务管理要优于编程式事务管理,这正是spring倡导的非侵入式的开发方式。声明式事务管理使业务代码不受污染,一个普通的POJO对象,只要加上注解就可以获得完全的事务支持。和编程式事务相比,声明式事务唯一不足地方是,它的最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。但是即便有这样的需求,也存在很多变通的方法,比如,可以将需要进行事务管理的代码块独立为方法等等。
声明式事务管理也有两种常用的方式,一种是基于tx和aop名字空间的xml配置文件,另一种就是基于@Transactional注解。显然基于注解的方式更简单易用,更清爽。


Spring 事务属性分析

事务管理对于企业应用而言至关重要。它保证了用户的每一次操作都是可靠的,即便出现了异常的访问情况,也不至于破坏后台数据的完整性。
在 Spring 中,事务是通过 TransactionDefinition 接口来定义的。该接口包含与事务属性有关的方法。
TransactionDefinition 接口中定义的主要方法

public interface TransactionDefinition{
   
    int getIsolationLevel();
    int getPropagationBehavior();
    int getTimeout();
    boolean isReadOnly();
}

接口只提供了获取属性的方法,而没有提供相关设置属性的方法。事务属性的设置完全是程序员控制的,因此程序员可以自定义任何设置属性的方法,而且保存属性的字段也没有任何要求。唯一的要求的是,Spring 进行事务操作的时候,通过调用以上接口提供的方法必须能够返回事务相关的属性取值。


事务的只读属性

事务的只读属性是指,对事务性资源进行只读操作或者是读写操作。所谓事务性资源就是指那些被事务管理的资源,比如数据源、 JMS 资源,以及自定义的事务性资源等等。如果确定只对事务性资源进行只读操作,那么我们可以将事务标志为只读的,以提高事务处理的性能。在 TransactionDefinition 中以 boolean 类型来表示该事务是否只读。


逻辑事务与物理事务

事务性资源实际打开的事务就是物理事务,如数据库的Connection打开的事务。Spring会为每个@Transactional方法创建一个事务范围,可以理解为是逻辑事务。
在逻辑事务中,大范围的事务称为外围事务,小范围的事务称为内部事务,外围事务可以包含内部事务,但在逻辑上是互相独立的。每一个这样的逻辑事务范围,都能够单独地决定rollback-only状态。
那么如何处理逻辑事务和物理事务之间的关联关系呢,这就是传播特性解决的问题。


事务的传播特性

所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。在TransactionDefinition定义中包括了如下几个表示传播行为的**常量**:
TransactionDefinition.PROPAGATION_REQUIRED 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。在相同的线程中,这是一种很好的默认方式安排。(例如,一个service外观/门面代理到若干个仓储方法,所有底层资源必须参与到service级别的事务里)
在标准的REQUIRED行为情况下,所有这样的逻辑事务范围映射到同一个物理事务。因此,在内部事务范围设置了rollback-only标记,确实会影响外围事务进行实际提交的机会。
注:默认,一个参与到外围事务的事务,会使用外围事务的特性,安静地忽略掉自己的隔离级别,超时值,只读标识等设置。当然可以在事务管理器上设置validateExistingTransactions标识为true,这样

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值