首页  

spring事务及注解     所属分类 spring 浏览量 17
事务的四大特性(ACID)
原子性(Atomicity):事务里的所有操作,要么全部成功执行,要么全部不执行  
一致性(Consistency):事务执行结束后,系统状态会从一个一致状态转变为另一个一致状态  
隔离性(Isolation):多个事务同时执行时,彼此之间不会相互干扰  
持久性(Durability):一旦事务提交成功,其结果就会永久保存下来  

Spring 定义的事务抽象接口

PlatformTransactionManager
事务管理器的核心接口,不同的数据源使用不同的实现类
DataSourceTransactionManager   HibernateTransactionManager等  

TransactionDefinition
定义事务的隔离级别、传播行为、超时时间和是否只读等属性  

TransactionStatus
当前事务的状态,可用于进行事务的提交、回滚等操作  

声明式事务管理  @Transactional 注解


@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
    String value() default "";
    Propagation propagation() default Propagation.REQUIRED;
    Isolation isolation() default Isolation.DEFAULT;
    int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
    boolean readOnly() default false;
    Class[] rollbackFor() default {};
    String[] rollbackForClassName() default {};
    Class[] noRollbackFor() default {};
    String[] noRollbackForClassName() default {};
}



传播行为决定了事务方法在被其他事务方法调用时的事务创建方式
Spring 定义了 7 种传播行为,常见的有以下几种:

REQUIRED(默认):如果当前没有事务,就创建一个新事务;如果已经存在事务,就加入该事务  
REQUIRES_NEW:无论当前是否存在事务,都会创建一个新的独立事务,原事务会被挂起  
SUPPORTS:如果当前存在事务,就加入该事务;如果不存在事务,就以非事务方式执行  
NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,就将其挂起  
MANDATORY:必须在一个已存在的事务中执行,如果当前没有事务,就会抛出异常  

隔离级别用于控制多个事务之间的可见性,解决脏读、不可重复读和幻读等问题  
Spring 支持以下隔离级别:

DEFAULT:使用数据库的默认隔离级别  
READ_UNCOMMITTED:允许读取尚未提交的数据,可能会导致脏读  
READ_COMMITTED:只能读取已经提交的数据,避免了脏读  
REPEATABLE_READ:确保在同一个事务中多次读取同一数据的结果是一致的,解决了不可重复读的问题  
SERIALIZABLE:最高的隔离级别,通过完全串行化事务执行来避免幻读,但会降低并发性能  



底层实现原理 Spring 的声明式事务是基于 AOP(面向切面编程)实现 事务增强器创建 Spring 会在启动时创建BeanFactoryTransactionAttributeSourceAdvisor事务增强器,该增强器包含: TransactionAttributeSource:用于解析@Transactional注解的属性 TransactionInterceptor:这是一个方法拦截器,负责处理事务逻辑 代理对象生成: 当 Bean 初始化完成后,Spring 会判断该 Bean 的方法是否标注了@Transactional注解 如果有,就会为其创建代理对象(可以是 JDK 动态代理或者 CGLIB 代理) 事务拦截处理 在目标方法执行前,会根据传播行为和隔离级别开启事务; 方法正常执行完成后,会提交事务; 如果方法抛出异常,会根据rollbackFor和noRollbackFor属性决定是否回滚事务
启用 Spring 声明式事务 @Configuration @EnableTransactionManagement public class AppConfig { // 配置数据源和事务管理器 @Bean public DataSource dataSource() { // 配置数据源 } @Bean public PlatformTransactionManager transactionManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } } 注意事项 方法可见性要求 @Transactional注解只能应用于public方法,因为 Spring 的 AOP 代理是基于方法调用的可见性来决定是否拦截的 自调用问题 在同一个类中,一个非事务方法调用另一个事务方法,事务不会生效,这是因为自调用不会经过代理对象 异常处理机制 默认情况下,只有RuntimeException及其子类会触发事务回滚 如果需要对受检异常进行回滚,需要通过rollbackFor属性进行指定 @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class) @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED) // 若当前没有事务,就创建一个新事务;若已有事务,则加入该事务 @Transactional(propagation = Propagation.REQUIRED) // 无论当前是否存在事务,都创建一个新的独立事务,原事务会被挂起 @Transactional(propagation = Propagation.REQUIRES_NEW) // 以非事务方式执行,如果当前存在事务,就将其挂起 @Transactional(propagation = Propagation.NOT_SUPPORTED) // 使用数据库的默认隔离级别 @Transactional(isolation = Isolation.DEFAULT) // 避免脏读,这是大多数数据库的默认隔离级别 @Transactional(isolation = Isolation.READ_COMMITTED) // 解决不可重复读问题 @Transactional(isolation = Isolation.REPEATABLE_READ) // 设置事务超时时间为 30 秒 @Transactional(timeout = 30) // 标记事务为只读,可进行性能优化 @Transactional(readOnly = true) // 发生 RuntimeException 或 Error 时回滚事务 @Transactional // 发生任何异常都回滚事务 @Transactional(rollbackFor = Exception.class) // 发生特定异常回滚事务,发生另一些异常则不回滚 @Transactional( rollbackFor = {SQLException.class, DataAccessException.class}, noRollbackFor = {MyBusinessException.class} )
多数据源事务管理 @Configuration public class MultiDataSourceConfig { @Bean(name = "primaryDataSource") public DataSource primaryDataSource() { // 配置主数据源 } @Bean(name = "secondaryDataSource") public DataSource secondaryDataSource() { // 配置从数据源 } @Bean(name = "primaryTransactionManager") public PlatformTransactionManager primaryTransactionManager( @Qualifier("primaryDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean(name = "secondaryTransactionManager") public PlatformTransactionManager secondaryTransactionManager( @Qualifier("secondaryDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } } // 在服务类中指定使用的事务管理器 @Service public class MultiDbService { @Autowired private UserRepository userRepository; @Autowired private ProductRepository productRepository; // 指定使用主数据源的事务管理器 @Transactional("primaryTransactionManager") public void updateUser(User user) { userRepository.save(user); } // 指定使用从数据源的事务管理器 @Transactional("secondaryTransactionManager") public void updateProduct(Product product) { productRepository.save(product); } }
嵌套事务应用场景 通过 Propagation.NESTED 可以实现嵌套事务,嵌套事务是外部事务的一部分,当嵌套事务回滚时,只会回滚当前嵌套事务的操作 @Service public class OrderService { @Autowired private OrderRepository orderRepository; @Autowired private PaymentService paymentService; @Transactional public void createOrder(Order order) { orderRepository.save(order); try { // 嵌套事务:支付处理 paymentService.processPayment(order); } catch (PaymentException e) { // 处理支付异常,但不影响订单创建 logger.error("Payment failed: {}", e.getMessage()); } } } @Service public class PaymentService { @Transactional(propagation = Propagation.NESTED) public void processPayment(Order order) throws PaymentException { // 处理支付逻辑 if (!paymentGateway.isAvailable()) { throw new PaymentException("Payment gateway is unavailable"); } } }

上一篇     下一篇
12种常见的提示词框架

Python3 VS Python2

FastAPI 和 Flask

《超有趣的 GPT AI 公子逆袭记》笔记

《大数据数学基础(Python语言描述)》 笔记

LangChain原理简介