首页 > 其他分享 >【SpringBoot系列】八、SpringBoot 中的事务处理

【SpringBoot系列】八、SpringBoot 中的事务处理

时间:2023-05-03 17:06:55浏览次数:43  
标签:事务 transaction 系列 SpringBoot 事务处理 springframework commit org throws


        前两章节主要讲解了在SpringBoot中关于对数据的操作,本章节将介绍如何进行事务处理。所有的数据访问技术都离不开事务处理,否则将会造成数据不一致。事务是一系列的动作,一旦其中有一个动作出现错误,必须全部回滚,系统将事务中对数据库的所有已完成的操作全部撤消,滚回到事务开始的状态,避免出现由于数据不一致而导致的接下来一系列的错误。事务的出现是为了确保数据的完整性和一致性,在目前企业级应用开发中,事务管理是必不可少的。

1、SpringBoot事务机制

       事务处理机制都会提供API来开启事务、提交事务来完成数据操作,或者在发生错误的时候回滚数据,避免数据的不完整性、不一致性。

       SpringBoot事务机制实质上就是Spring的事务机制,是采用统一的机制处理来自不同数据访问技术的事务处理,提供了一个接口 PlatformTransactionManager,已经为不同数据访问技术可以进行不同的实现,如下表。

数据访问技术及实现

数据访问技术

实现类

JDBC

DataSourceTransactionManager

JPA

JpaTransactionManager

Hibernate

HibernateTransactionManager

JDO

JdoTransactionManager

分布式事务

JtaTransactionManager

涉及到接口关系如下:

【SpringBoot系列】八、SpringBoot 中的事务处理_SpringBoot

接口PlatformTransactionManager源码如下:

/*
 * Copyright 2002-2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.transaction;

import org.springframework.lang.Nullable;

/**
 * This is the central interface in Spring's transaction infrastructure.
 * Applications can use this directly, but it is not primarily meant as API:
 * Typically, applications will work with either TransactionTemplate or
 * declarative transaction demarcation through AOP.
 *
 * <p>For implementors, it is recommended to derive from the provided
 * {@link org.springframework.transaction.support.AbstractPlatformTransactionManager}
 * class, which pre-implements the defined propagation behavior and takes care
 * of transaction synchronization handling. Subclasses have to implement
 * template methods for specific states of the underlying transaction,
 * for example: begin, suspend, resume, commit.
 *
 * <p>The default implementations of this strategy interface are
 * {@link org.springframework.transaction.jta.JtaTransactionManager} and
 * {@link org.springframework.jdbc.datasource.DataSourceTransactionManager},
 * which can serve as an implementation guide for other transaction strategies.
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @since 16.05.2003
 * @see org.springframework.transaction.support.TransactionTemplate
 * @see org.springframework.transaction.interceptor.TransactionInterceptor
 * @see org.springframework.transaction.interceptor.TransactionProxyFactoryBean
 */
public interface PlatformTransactionManager {

	/**
	 * Return a currently active transaction or create a new one, according to
	 * the specified propagation behavior.
	 * <p>Note that parameters like isolation level or timeout will only be applied
	 * to new transactions, and thus be ignored when participating in active ones.
	 * <p>Furthermore, not all transaction definition settings will be supported
	 * by every transaction manager: A proper transaction manager implementation
	 * should throw an exception when unsupported settings are encountered.
	 * <p>An exception to the above rule is the read-only flag, which should be
	 * ignored if no explicit read-only mode is supported. Essentially, the
	 * read-only flag is just a hint for potential optimization.
	 * @param definition TransactionDefinition instance (can be {@code null} for defaults),
	 * describing propagation behavior, isolation level, timeout etc.
	 * @return transaction status object representing the new or current transaction
	 * @throws TransactionException in case of lookup, creation, or system errors
	 * @throws IllegalTransactionStateException if the given transaction definition
	 * cannot be executed (for example, if a currently active transaction is in
	 * conflict with the specified propagation behavior)
	 * @see TransactionDefinition#getPropagationBehavior
	 * @see TransactionDefinition#getIsolationLevel
	 * @see TransactionDefinition#getTimeout
	 * @see TransactionDefinition#isReadOnly
	 */
	TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;

	/**
	 * Commit the given transaction, with regard to its status. If the transaction
	 * has been marked rollback-only programmatically, perform a rollback.
	 * <p>If the transaction wasn't a new one, omit the commit for proper
	 * participation in the surrounding transaction. If a previous transaction
	 * has been suspended to be able to create a new one, resume the previous
	 * transaction after committing the new one.
	 * <p>Note that when the commit call completes, no matter if normally or
	 * throwing an exception, the transaction must be fully completed and
	 * cleaned up. No rollback call should be expected in such a case.
	 * <p>If this method throws an exception other than a TransactionException,
	 * then some before-commit error caused the commit attempt to fail. For
	 * example, an O/R Mapping tool might have tried to flush changes to the
	 * database right before commit, with the resulting DataAccessException
	 * causing the transaction to fail. The original exception will be
	 * propagated to the caller of this commit method in such a case.
	 * @param status object returned by the {@code getTransaction} method
	 * @throws UnexpectedRollbackException in case of an unexpected rollback
	 * that the transaction coordinator initiated
	 * @throws HeuristicCompletionException in case of a transaction failure
	 * caused by a heuristic decision on the side of the transaction coordinator
	 * @throws TransactionSystemException in case of commit or system errors
	 * (typically caused by fundamental resource failures)
	 * @throws IllegalTransactionStateException if the given transaction
	 * is already completed (that is, committed or rolled back)
	 * @see TransactionStatus#setRollbackOnly
	 */
	void commit(TransactionStatus status) throws TransactionException;

	/**
	 * Perform a rollback of the given transaction.
	 * <p>If the transaction wasn't a new one, just set it rollback-only for proper
	 * participation in the surrounding transaction. If a previous transaction
	 * has been suspended to be able to create a new one, resume the previous
	 * transaction after rolling back the new one.
	 * <p><b>Do not call rollback on a transaction if commit threw an exception.</b>
	 * The transaction will already have been completed and cleaned up when commit
	 * returns, even in case of a commit exception. Consequently, a rollback call
	 * after commit failure will lead to an IllegalTransactionStateException.
	 * @param status object returned by the {@code getTransaction} method
	 * @throws TransactionSystemException in case of rollback or system errors
	 * (typically caused by fundamental resource failures)
	 * @throws IllegalTransactionStateException if the given transaction
	 * is already completed (that is, committed or rolled back)
	 */
	void rollback(TransactionStatus status) throws TransactionException;

}

2、声明式事务

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

      Spring支持声明式事务,被注解的方法在被调用时,Spring开启一个新的事务,当方法无异常结束后,Spring会提交这个事务。

@Transactional
public void insertUser(User user) {
   //数据库表的操作
    ……
}

注:

(1)@Transactional是来自org.springframework.transaction.annotation包的。

(2)@Transactional不仅可以注解在方法上,也可以注解在类上。当注解在类上时,意味着此类的所有public方法都是开启事务的。如果类级别和方法级别同时使用了@Transactional注解,则使用在类级别的注解会重载方法级别的注解。

以下为注解@Transactional源码:

(为了缩小所占篇数,故去掉注释部分)

package org.springframework.transaction.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.core.annotation.AliasFor;
import org.springframework.transaction.TransactionDefinition;


@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {

	@AliasFor("transactionManager")
	String value() default "";
	
	@AliasFor("value")
	String transactionManager() default "";
	
	Propagation propagation() default Propagation.REQUIRED;

	Isolation isolation() default Isolation.DEFAULT;

	int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;

	boolean readOnly() default false;

	Class<? extends Throwable>[] rollbackFor() default {};

	String[] rollbackForClassName() default {};
	
	Class<? extends Throwable>[] noRollbackFor() default {};

	String[] noRollbackForClassName() default {};
}

属性说明如下表:

属性

类型

描述

value

String

可选的限定描述符,指定使用的事务管理器

propagation

enum: Propagation

定义事务的生命周期,有REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER、NESTED,详细含义可查阅枚举类org.springframework.transaction.annotation.Propagation源码。

isolation

enum: Isolation

可选的事务隔离级别设置,决定了事务的完整性

readOnly

boolean

读写或只读事务,默认读写

timeout

int (in seconds granularity)

事务超时时间设置

rollbackFor

Class对象数组,必须继承自Throwable

导致事务回滚的异常类数组

rollbackForClassName

类名数组,必须继承自Throwable

导致事务回滚的异常类名字数组

noRollbackFor

Class对象数组,必须继承自Throwable

不会导致事务回滚的异常类数组

noRollbackForClassName

类名数组,必须继承自Throwable

不会导致事务回滚的异常类名字数组

在SpringBoot中,建议采用注解@Transactional进行事务的控制。

 

 

【SpringBoot系列】八、SpringBoot 中的事务处理_java_02

标签:事务,transaction,系列,SpringBoot,事务处理,springframework,commit,org,throws
From: https://blog.51cto.com/xcbeyond/6241392

相关文章

  • 【SpringBoot系列】七、SpringBoot 中使用Redis缓存
        在项目中对数据的访问往往都是直接访问数据库的方式,但如果对数据的访问量很大或者访问很频繁的话,将会对数据库来很大的压力,甚至造成数据库崩溃。为了解决这类问题redis数据库脱颖而出,redis数据库出现时是以非关系数据库的光环展示在广大程序猿的面前的,后来redis的迭代版......
  • 【SpringBoot系列】四、SpringBoot特性_外部化配置(properties文件配置)
            SpringBoot允许将配置进行外部化(externalize),这样你就能够在不同的环境下使用相同的代码。你可以使用properties文件,yaml文件,环境变量和命令行参数来外部化配置。使用@Value注解,可以直接将属性值注入到beans中,然后通过Spring的Environment抽象或通过@ConfigurationP......
  • 【SpringBoot系列】三、SpringBoot特性_SpringApplication类(自定义Banner)
        SpringApplication类作为SpringBoot最基本、最核心的类,在main方法中用来启动SpringBoot项目。一般情况下,只需在main方法中使用SpringApplication.run静态方法来启动项目:packagecom.xcbeyond.springboot;importorg.springframework.boot.SpringApplication;importorg.......
  • 【SpringBoot 系列】一、SpringBoot项目搭建
    一、引言:什么是springboot?    SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。用我的话来理解,就是springboot其实不是什么新的框架,它默认配......
  • java基于springboot+vue非前后端分离的影城管理系统、影院销售管理系统,附源码+文档+PP
    1、项目介绍本影城管理系统主要包括二大功能模块,即用户功能模块和管理员功能模块。(1)管理员模块:系统中的核心用户是管理员,管理员登录后,通过管理员功能来管理后台系统。主要功能有:首页、个人中心、用户管理、电影类型管理、放映厅管理、电影信息管理、购票统计管理、系统管理、订......
  • idea创建SpringBoot项目报错For artifact {mysql:mysql-connector-java:null:jar}: Th
    Forartifact{mysql:mysql-connector-java:null:jar}:Theversioncannotbeempty.报错如图:pom.xml文件如图:添加版本号:就好了......
  • Springboot 之 Mybatis-plus 多数据源
    简介Mybatis-puls多数据源的使用,采用的是官方提供的dynamic-datasource-spring-boot-starter包的@DS注解,具体可以参考官网:https://gitee.com/baomidou/dynamic-datasource-spring-boot-starterpom.xml文件引入如下依赖主要引入dynamic-datasource-spring-boot-starter包<project......
  • Blazor学习之旅系列总结目录
    1什么是Blazor?Blazor是微软近年来主推的,基于C#、HTML与CSS来构建交互式WebUI的框架。 借助Blazor,开发人员可以使用C#生成客户端和服务器代码。他们还可以与前端客户端代码和后端逻辑共享代码和库。使用C#生成所有代码可简化在前端和后端之间共享数据,重复使用代码以加速......
  • 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(12)- 从SD/eMMC启动
    大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是恩智浦i.MXRT1xxx系列MCU的SD/eMMC卡启动。最近在恩智浦官方社区上支持了一个关于i.MXRT从SD卡启动的案例,这让痞子衡想起了一年前写过的一篇《i.MXRT600从SD/eMMC启动》,那一篇重点介绍了基于eMMC设......
  • 学系统集成项目管理工程师(中项)系列16b_风险管理(下)
    1. 规划风险应对1.1. 针对项目目标,制订提高机会、降低威胁的方案和措施的过程1.2. 制订风险应对措施1.3. 制订风险应对计划1.4. 次生风险是实施风险应对措施的直接结果1.5. 应对措施必须与风险的重要性相匹配,能经济有效地应对挑战1.5.1. 【22下选67】1.6. 经常要......