自学内容网 自学内容网

Spring事务详细

Spring事务详细

一、事务的基本概念

1.1 定义

事务(Transaction)是指由一条或多条操作数据库的SQL语句组成的一个不可分割的工作单元。这些操作要么全部执行成功,要么全部失败,以确保数据的一致性和完整性。

1.2 特性(ACID)

  • 原子性(Atomicity):事务中的所有操作是不可再分割的原子单位,事务中的所有操作要么全部执行成功,要么全部执行失败。
  • 一致性(Consistency):事务执行后,数据库状态应该与其他业务规则保持一致。例如,在转账业务中,无论事务执行成功与否,参与的两个账号余额之和是不应发生改变的。
  • 隔离性(Isolation):事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
  • 持久性(Durability):一旦事务提交成功,事务中所有的数据操作都必须持久化到数据库中,即使提交事务后,数据库马上崩溃,重启之后也应该保证数据恢复。

二、事务的隔离级别

事务的隔离级别是为了解决并发操作中的脏读、不可重复读和幻读等问题而设置的。隔离级别由低到高依次为:

  1. READ UNCOMMITTED(读未提交):允许一个事务读取到另一个事务未提交的数据,会产生脏读。
  2. READ COMMITTED(读已提交):一个事务要等到另一个事务已经提交了才会读取到数据,会产生不可重复读。
  3. REPEATABLE READ(可重复读):一个事务读取的时候,会将数据锁起来,不允许做修改,但会产生幻读。
  4. SERIALIZABLE(序列化):最高级别,将事务串行化顺序执行,可以避免脏读、不可重复读和幻读,但比较消耗性能,一般不使用。

三、Spring事务

3.1 概念

Spring事务是指在Spring框架中对于数据库操作的一种支持,它通过对一组数据库操作进行整体控制来保证数据的一致性和完整性。Spring事务可以保证在一组数据库操作执行时,要么所有操作都执行成功,要么所有操作都回滚到之前的状态。

3.2 实现方式

Spring中的事务操作分为两类:编程式事务和声明式事务。

3.2.1 编程式事务

编程式事务需要手动编写代码来控制事务的开启、提交和回滚。虽然这种方式可以实现灵活的事务管理,但代码较为繁琐,实际开发中较少使用。

3.2.2 声明式事务

声明式事务通过注解(如@Transactional)来自动管理事务,无需手动编写事务控制代码。这种方式简单易用,是Spring推荐的事务管理方式。

3.3 核心API

3.3.1 PlatformTransactionManager

Spring将事务管理交给了事务管理器PlatformTransactionManager,Spring为各个平台提供了相应的事务管理器,比如为JDBC提供的DataSourceTransactionManager

public interface PlatformTransactionManager extends TransactionManager {
    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
    void commit(TransactionStatus status) throws TransactionException;
    void rollback(TransactionStatus status) throws TransactionException;
}
3.3.2 TransactionDefinition

TransactionDefinition描述事务的隔离级别、传播行为、超时时间、是否只读等属性。

public interface TransactionDefinition {
    default int getPropagationBehavior() {
        return PROPAGATION_REQUIRED;
    }

    default int getIsolationLevel() {
        return ISOLATION_DEFAULT; // 根据数据库自动选择隔离级别
    }

    default int getTimeout() {
        return TIMEOUT_DEFAULT;
    }

    default boolean isReadOnly() {
        return false;
    }
}

3.4 声明式事务配置

3.4.1 Maven依赖

Spring事务需要spring-jdbcspring-tx两个模块,以及spring-aspects用于AOP支持。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.3.19</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.3.19</version>
</dependency>
3.4.2 Spring配置文件
<!-- 配置数据源 -->
<bean id="dataSource " class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/yourdatabase"/>
    <property name="username" value="root"/>
    <property name="password" value="password"/>
</bean>

<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

<!-- 启用注解事务管理 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
3.4.3 使用@Transactional注解

在Service层的方法上使用@Transactional注解来声明事务的边界。Spring会在运行时自动为这些方法添加事务管理逻辑。

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class YourService {

    @Transactional
    public void yourTransactionalMethod() {
        // 数据库操作...
        // 如果这里抛出运行时异常,则事务会自动回滚
    }

    // 也可以对异常进行精细控制
    @Transactional(rollbackFor = Exception.class)
    public void yourTransactionalMethodWithRollback() {
        // 数据库操作...
        // 这里指定了所有异常都会触发事务回滚
    }
}

3.5 注意事项

  1. 事务的传播行为@Transactionalpropagation属性用于定义事务的传播行为,如PROPAGATION_REQUIRED(如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务)、PROPAGATION_REQUIRES_NEW(创建一个新的事务,并暂停当前事务(如果存在))。

  2. 异常处理:默认情况下,Spring事务仅在遇到运行时异常(RuntimeException及其子类)和错误(Error及其子类)时回滚。如果需要,可以通过rollbackFornoRollbackFor属性来自定义哪些异常会触发事务回滚。

  3. 只读事务:如果事务只包含读取操作,可以将@TransactionalreadOnly属性设置为true,这有助于数据库进行一些优化(如不使用写锁)。

  4. 事务超时:可以通过@Transactionaltimeout属性来设置事务的超时时间(单位为秒),如果在指定的时间内事务没有完成,则自动回滚。

  5. 代理机制:Spring的声明式事务是通过AOP(面向切面编程)实现的,这意味着@Transactional注解只能应用于被Spring容器管理的bean的方法上。如果直接调用同一个类中的另一个@Transactional注解的方法,事务管理将不会生效,因为此时不是通过代理对象调用的。

通过上述介绍,我们可以对Spring事务有一个全面的了解,包括事务的基本概念、隔离级别、Spring事务的实现方式、核心API以及如何在Spring项目中配置和使用声明式事务。


原文地址:https://blog.csdn.net/2401_83447580/article/details/140825380

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!