spring事务的传播级别

Spring事务是Java应用程序中经常使用的功能之一,它可以帮助我们管理数据库操作过程中的异常和数据一致性问题。在Spring框架中,事务的传播级别定义了七种 类型,分别是:REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER、NESTED。

1、REQUIRED(默认传播级别)

如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是最常见的传播级别,也是Spring的默认传播级别。

2、SUPPORTS

支持当前事务,如果当前存在事务,则加入该事务;如果当前没有事务,就以非事务方式执行。

3、MANDATORY

必须在事务中执行,如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。

4、REQUIRES_NEW

必须创建一个新的事务,如果当前存在事务,则把当前事务挂起。

5、NOT_SUPPORTED

以非事务方式执行操作,如果当前存在事务,则把当前事务挂起。

6、NEVER

不能在事务中执行,以非事务方式执行操作。如果当前存在事务,则抛出异常。

7、NESTED

如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则与REQUIRED类似。

以上是Spring事务传播级别的七种类型及其作用。在实际开发中,我们需要根据具体的业务场景来选择合适的传播级别。例如,如果我们需要确保多个服务方法之间的原子性操作,则需要将传播级别设置为REQUIRED或REQUIRES_NEW。而如果我们只需要支持当前事务而不需要进行额外的处理,则可以将传播级别设置为SUPPORTS或NOT_SUPPORTED。

示例

下面是一个Spring事务传播级别的示例:

首先,我们需要在Spring配置文件中配置一个数据源和事务管理器:

复制代码
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/test"/>
    <property name="username" value="root"/>
    <property name="password" value="123456"/>
</bean>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

然后,我们可以定义一个Service类,并在其中使用@Transactional注解来指定事务的传播级别。例如,如果我们需要确保多个服务方法之间的原子性操作,则需要将传播级别设置为REQUIRED或REQUIRES_NEW。而如果我们只需要支持当前事务而不需要进行额外的处理,则可以将传播级别设置为SUPPORTS或NOT_SUPPORTED。

复制代码
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserService {
    // 使用REQUIRED传播级别,如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
    @Transactional(propagation = Propagation.REQUIRED)
    public void addUser() {
        // ...添加用户的逻辑...
    }
    
    // 使用REQUIRES_NEW传播级别,必须创建一个新的事务,如果当前存在事务,则把当前事务挂起。
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void updateUser() {
        // ...更新用户的逻辑...
    }
}

在上面的示例中,我们使用了两种不同的传播级别:REQUIRED和REQUIRES_NEW。当我们调用addUser()方法时,如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。而当我们调用updateUser()方法时,必须创建一个新的事务,如果当前存在事务,则把当前事务挂起。这样,我们就可以确保多个服务方法之间的原子性操作了。

什么是原子操作?

原子性操作,也被称为原子操作,是一个不可分割的操作单元。这意味着在执行过程中,该操作不会被其他线程或进程中断,要么完整地执行,要么完全不执行。例如,将一个整数从1增加到2的过程就是一个原子性操作,因为这个操作只涉及到一个赋值操作,即i=i+1。

在数据库中,原子性操作同样非常重要。以转账为例,从A账户向B账户转账1000块钱的整个过程,包括从A账户中扣除1000块钱和向B账户中增加1000块钱这两个步骤,被统称为一个事务。如果其中任何一个步骤失败,整个事务都会回滚到原始状态,这确保了数据的一致性和完整性。

此外,原子性操作在多线程编程中也十分关键。所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何切换到另一线程的情况发生。因此,原子性操作是实现线程安全的重要手段之一。

相关推荐
码农水水5 分钟前
京东Java面试被问:HTTP/2的多路复用和头部压缩实现
java·开发语言·分布式·http·面试·php·wpf
DBA小马哥20 分钟前
从MongoDB迁移到金仓数据库:数据模型与业务连续性难题的保姆级指南
数据库·mongodb·dba
你怎么知道我是队长33 分钟前
C语言---未定义行为
java·c语言·开发语言
没有bug.的程序员1 小时前
Java 序列化:Serializable vs. Protobuf 的性能与兼容性深度对比
java·开发语言·后端·反射·序列化·serializable·protobuf
QZ166560951591 小时前
低误差率、高性能、符合审计要求的金融数据库审计和监测最佳实践指南
数据库·金融
愚公移码1 小时前
蓝凌EKP产品:主文档权限机制浅析
java·前端·数据库·蓝凌
Remember_9931 小时前
【LeetCode精选算法】滑动窗口专题一
java·数据结构·算法·leetcode·哈希算法
开开心心就好1 小时前
音频编辑工具,多端支持基础剪辑易操作
java·网络·windows·java-ee·电脑·maven·excel
此生只爱蛋1 小时前
【Redis】持久化
数据库·redis
凯子坚持 c1 小时前
Protocol Buffers C++ 进阶数据类型与应用逻辑深度解析
java·服务器·c++