Spring的事务传播机制和隔离级别

Spring 提供了强大的事务管理机制,通过 @Transactional 注解或程序化事务管理方式,开发者可以轻松地在应用中启用事务特性。事务传播机制和隔离级别是 Spring 事务管理中的两个重要方面,了解它们有助于更好地控制事务的行为,确保数据的一致性和完整性。

1. 事务传播机制(Transaction Propagation)

事务传播机制定义了当一个事务方法被另一个事务方法调用时,事务如何传播。Spring 提供了七种事务传播行为:

1.1 PROPAGATION_REQUIRED

如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。大多数情况下,这是默认的传播行为。

1.2 PROPAGATION_REQUIRES_NEW

总是创建一个新的事务。如果当前存在事务,则将当前事务挂起。在嵌套事务中较为常用。

1.3 PROPAGATION_SUPPORTS

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

1.4 PROPAGATION_NOT_SUPPORTED

总是以非事务方式执行,如果当前存在事务,则将当前事务挂起。

1.5 PROPAGATION_NEVER

总是以非事务方式执行,如果当前存在事务,则抛出异常。

1.6 PROPAGATION_MANDATORY

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

1.7 PROPAGATION_NESTED

如果当前存在事务,则创建一个嵌套事务(使用保存点);如果当前没有事务,则创建一个新的事务。需要底层数据库支持嵌套事务。

2. 事务隔离级别(Transaction Isolation Level)

事务隔离级别定义了一个事务可以看到其他事务的哪些数据状态。隔离级别越高,数据一致性越好,但并发性能越低。Spring 支持以下五种隔离级别:

2.1 ISOLATION_DEFAULT

使用底层数据库的默认隔离级别。大多数数据库的默认隔离级别是 READ_COMMITTED

2.2 ISOLATION_READ_UNCOMMITTED

最低的隔离级别,允许读取未提交的数据(脏读)。可能会导致脏读、不可重复读和幻读。

2.3 ISOLATION_READ_COMMITTED

允许读取已提交的数据,防止脏读。可能会导致不可重复读和幻读。

2.4 ISOLATION_REPEATABLE_READ

防止脏读和不可重复读。可能会导致幻读。

2.5 ISOLATION_SERIALIZABLE

最高的隔离级别,完全锁定相关数据,防止脏读、不可重复读和幻读。这是最慢的隔离级别,但确保了最高的数据一致性。

示例代码

以下是一个示例代码,展示了如何使用 @Transactional 注解来配置事务传播机制和隔离级别:

复制代码

java复制代码

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @Service public class TransactionalService { @Autowired private JdbcTemplate jdbcTemplate; @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED) public void methodA() { // 执行一些数据库操作 jdbcTemplate.update("UPDATE account SET balance = balance - 100 WHERE id = 1"); methodB(); } @Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.SERIALIZABLE) public void methodB() { // 执行一些数据库操作 jdbcTemplate.update("UPDATE account SET balance = balance + 100 WHERE id = 2"); } }

主程序
复制代码

java复制代码

import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class TransactionalExample { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); TransactionalService transactionalService = context.getBean(TransactionalService.class); transactionalService.methodA(); } }

配置类
复制代码

java复制代码

import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.support.TransactionTemplate; import javax.sql.DataSource; @Configuration @EnableTransactionManagement public class AppConfig { @Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/testdb"); dataSource.setUsername("username"); dataSource.setPassword("password"); return dataSource; } @Bean public PlatformTransactionManager transactionManager() { return new org.springframework.jdbc.datasource.DataSourceTransactionManager(dataSource()); } @Bean public JdbcTemplate jdbcTemplate(DataSource dataSource) { return new JdbcTemplate(dataSource); } }

总结

Spring 提供了强大的事务管理机制,通过 @Transactional 注解可以方便地配置事务传播行为和隔离级别:

  1. 事务传播机制 :定义了事务方法在被另一个事务方法调用时的行为。常见的传播行为包括 PROPAGATION_REQUIREDPROPAGATION_REQUIRES_NEWPROPAGATION_SUPPORTS 等。
  2. 事务隔离级别 :定义了一个事务对其他事务的可见性。常见的隔离级别包括 ISOLATION_READ_UNCOMMITTEDISOLATION_READ_COMMITTEDISOLATION_REPEATABLE_READISOLATION_SERIALIZABLE

了解事务传播机制和隔离级别有助于写出更健壮和高效的事务管理代码,确保数据的一致性和完整性。

Spring 提供了强大的事务管理机制,通过 @Transactional 注解或程序化事务管理方式,开发者可以轻松地在应用中启用事务特性。事务传播机制和隔离级别是 Spring 事务管理中的两个重要方面,了解它们有助于更好地控制事务的行为,确保数据的一致性和完整性。

1. 事务传播机制(Transaction Propagation)

事务传播机制定义了当一个事务方法被另一个事务方法调用时,事务如何传播。Spring 提供了七种事务传播行为:

1.1 PROPAGATION_REQUIRED

如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。大多数情况下,这是默认的传播行为。

1.2 PROPAGATION_REQUIRES_NEW

总是创建一个新的事务。如果当前存在事务,则将当前事务挂起。在嵌套事务中较为常用。

1.3 PROPAGATION_SUPPORTS

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

1.4 PROPAGATION_NOT_SUPPORTED

总是以非事务方式执行,如果当前存在事务,则将当前事务挂起。

1.5 PROPAGATION_NEVER

总是以非事务方式执行,如果当前存在事务,则抛出异常。

1.6 PROPAGATION_MANDATORY

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

1.7 PROPAGATION_NESTED

如果当前存在事务,则创建一个嵌套事务(使用保存点);如果当前没有事务,则创建一个新的事务。需要底层数据库支持嵌套事务。

2. 事务隔离级别(Transaction Isolation Level)

事务隔离级别定义了一个事务可以看到其他事务的哪些数据状态。隔离级别越高,数据一致性越好,但并发性能越低。Spring 支持以下五种隔离级别:

2.1 ISOLATION_DEFAULT

使用底层数据库的默认隔离级别。大多数数据库的默认隔离级别是 READ_COMMITTED

2.2 ISOLATION_READ_UNCOMMITTED

最低的隔离级别,允许读取未提交的数据(脏读)。可能会导致脏读、不可重复读和幻读。

2.3 ISOLATION_READ_COMMITTED

允许读取已提交的数据,防止脏读。可能会导致不可重复读和幻读。

2.4 ISOLATION_REPEATABLE_READ

防止脏读和不可重复读。可能会导致幻读。

2.5 ISOLATION_SERIALIZABLE

最高的隔离级别,完全锁定相关数据,防止脏读、不可重复读和幻读。这是最慢的隔离级别,但确保了最高的数据一致性。

示例代码

以下是一个示例代码,展示了如何使用 @Transactional 注解来配置事务传播机制和隔离级别:

复制代码

java复制代码

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @Service public class TransactionalService { @Autowired private JdbcTemplate jdbcTemplate; @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED) public void methodA() { // 执行一些数据库操作 jdbcTemplate.update("UPDATE account SET balance = balance - 100 WHERE id = 1"); methodB(); } @Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.SERIALIZABLE) public void methodB() { // 执行一些数据库操作 jdbcTemplate.update("UPDATE account SET balance = balance + 100 WHERE id = 2"); } }

主程序
复制代码

java复制代码

import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class TransactionalExample { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); TransactionalService transactionalService = context.getBean(TransactionalService.class); transactionalService.methodA(); } }

配置类
复制代码

java复制代码

import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.support.TransactionTemplate; import javax.sql.DataSource; @Configuration @EnableTransactionManagement public class AppConfig { @Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/testdb"); dataSource.setUsername("username"); dataSource.setPassword("password"); return dataSource; } @Bean public PlatformTransactionManager transactionManager() { return new org.springframework.jdbc.datasource.DataSourceTransactionManager(dataSource()); } @Bean public JdbcTemplate jdbcTemplate(DataSource dataSource) { return new JdbcTemplate(dataSource); } }

总结

Spring 提供了强大的事务管理机制,通过 @Transactional 注解可以方便地配置事务传播行为和隔离级别:

  1. 事务传播机制 :定义了事务方法在被另一个事务方法调用时的行为。常见的传播行为包括 PROPAGATION_REQUIREDPROPAGATION_REQUIRES_NEWPROPAGATION_SUPPORTS 等。
  2. 事务隔离级别 :定义了一个事务对其他事务的可见性。常见的隔离级别包括 ISOLATION_READ_UNCOMMITTEDISOLATION_READ_COMMITTEDISOLATION_REPEATABLE_READISOLATION_SERIALIZABLE

了解事务传播机制和隔离级别有助于写出更健壮和高效的事务管理代码,确保数据的一致性和完整性。

相关推荐
Elastic 中国社区官方博客7 小时前
需要知道某个同义词是否实际匹配了你的 Elasticsearch 查询吗?
大数据·数据库·elasticsearch·搜索引擎·全文检索
JustMove0n7 小时前
互联网大厂Java面试全流程问答及技术详解
java·jvm·redis·mybatis·dubbo·springboot·多线程
SimonKing7 小时前
5分钟学会!把代码从本地推送到 GitHub,就是这么简单
java·后端·程序员
玹外之音7 小时前
Spring AI 11 种文档切割策略全解析
java·spring·ai编程
熊文豪8 小时前
MySQL迁移的“隐形坑”与电科金仓的“零改造”破局之道
数据库·mysql
Java练习两年半8 小时前
互联网大厂 Java 求职面试:技术栈与微服务深度解析
java·微服务·面试·技术栈
Seven978 小时前
类字节码:揭开Java虚拟机运行机制的神秘面纱
java
lang201509288 小时前
从零开始掌握 Logback:Java 日志框架的“Hello World”实战指南
java·单元测试·logback
萝卜白菜。8 小时前
ClassCastException: oracle.sql.BLOB cannot be cast to oracle.sql.BLOB问题
数据库·oracle
lang201509288 小时前
Logback 过滤器深度指南:从“三值逻辑”到高性能拦截
java·网络·logback