Spring @Transaction 注解用法

一、概述

        在 Spring 框架中,@Transaction 注解是用于管理事务的一种重要工具。事务是一组必须全部成功或全部失败的数据库操作。在应用程序中,一次事务可能包括多个对数据库的读写操作。@Transaction 注解可以确保这些操作要么全部成功,要么全部失败,从而保持数据的一致性。当然它不支持跨服务或者跨数据库的事物,只支持本地同一线程下的事物一致性。        

二、@Transaction 注解的用法

  1. 事务的四种行为

Spring 的 @Transaction 注解提供了四种事务行为,分别对应于四个方法:

(1)@Transactional(readOnly = true)
此方法的事务只读,意味着在这个事务中不会对数据库进行修改。它可用于查询等只读操作的事务。

(2)@Transactional
这是默认的事务行为。如果没有指定其他行为,或者指定 readOnly 为 false,那么这个事务就是可写的。如果这个事务发生异常,那么所有对数据库的修改都会被回滚。

(3)@Transactional(readOnly = false)
这个事务可以读写,如果发生异常,也会回滚所有对数据库的修改。

(4)@Transactional(noRollbackFor = Exception.class)
这个事务可以读写,即使发生指定的异常也不会回滚。

  1. @Transaction 注解的使用范围

@Transaction 注解可以应用在方法上,也可以应用在类上。当它应用在类上时,它表示这个类的所有 public 方法都将运行在一个事务的上下文中。当它应用在方法上时,它只对该方法进行事务管理。

三、使用 @Transaction 的注意事项

  1. 使用 @Transactional 注解需要 Spring 的 AOP 支持,因此请确保已经正确配置了 Spring 的 AOP。
  2. 如果使用了 Spring 的 JTA(Java Transaction API)支持,@Transactional 注解将覆盖 JTA 的事务管理。
  3. 如果 @Transactional 注解和 JDBC、Hibernate、JPA 的 SavepointManager 或任何其他事务管理器一起使用,它必须被放在底层的事务管理器的上层,否则无法工作。
  4. 在 Spring 的 JPA 中,如果在保存实体时出现异常,JPA 将自动回滚事务。如果需要在应用程序中处理回滚,请关闭 JPA 的自动回滚。
  5. 在 Spring 的 Hibernate 中,如果在保存实体时出现异常,Hibernate 将自动回滚事务。如果需要在应用程序中处理回滚,请关闭 Hibernate 的自动回滚。
  6. 在使用 @Transactional 注解时,请注意它只对 public 方法有效。如果把它用在非 public 方法上,Spring 将抛出一个异常。如果要事务管理 protected 或 package-private 方法,需要自定义一个 AspectJ 切面来处理。
  7. 在使用 Spring 的多线程应用程序中,使用 @Transactional 时必须加上 propagation="REQUIRED",否则可能会发生并发问题。因为如果没有指定 propagation 属性,Spring 会为每个线程创建一个新的事务。
  8. 如果使用 @Transactional 管理事务,但没有配置好 Spring 的事务管理器,那么在运行时将抛出 NoSuchBeanDefinitionException 异常。要解决这个问题,需要在 Spring 的配置文件中添加一个 Bean,类型为 PlatformTransactionManager。
  9. 如果在应用程序中使用多个数据源,并且需要每个数据源都有自己的一组事务(例如在多模块应用程序中),那么需要自定义 Spring 的 PlatformTransactionManager Bean 来为每个数据源指定一个单独的事务管理器。
  10. 如果使用了 Spring 的声明式事务管理功能(例如 @Transactional 注解),那么不应该使用程序式事务管理功能(例如 beginTransaction() / commit())。否则可能会导致事务的不一致状态。
  11. 在使用 @Transactional 注解时,应该尽量避免在事务方法中调用其他具有 @Transactional 注解的方法。否则可能会导致嵌套事务和不可预测的事务行为。如果确实需要嵌套事务,应该明确地配置它们以避免冲突。
  12. 在使用 @Transactional 注解时,应该注意避免在事务方法中调用外部方法(例如网络调用或阻塞 I/O)。否则可能会导致事务超时或其他与事务管理相关的问题。如果必须在事务方法中调用外部方法,应该考虑使用适应性的事务策略来处理潜在的事务问题。
  13. 在使用 @Transactional 注解时,应该谨慎地处理 Spring 的propagation属性。不同的propagation属性可能会导致不同的事务行为和适用场景。例如,使用propagation="NESTED"可以在嵌套事务中创建一个新的事务,而不会与外部事务关联起来;使用propagation="REQUIRED"会与外部事务关联起来,并在外部事务失败时回滚内部事务;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring Boot 中,@Transactional 注解用于启用事务管理。它可以应用于类级别和方法级别。当它被应用在一个类上时,它将被应用于类中的所有方法。当它被应用在方法级别时,它仅应用于该方法。以下是@ Transactional 注解用法: 在类级别使用 @Transactional 注解: ``` @Service @Transactional public class UserServiceImpl implements UserService { // code } ``` 在方法级别使用 @Transactional 注解: ``` @Service public class UserServiceImpl implements UserService { @Override @Transactional public void saveUser(User user) { // code } } ``` 在方法级别使用 @Transactional 注解时,可以使用 propagation 属性来指定事务传播行为。例如,以下是一个示例: ``` @Service public class UserServiceImpl implements UserService { @Override @Transactional(propagation = Propagation.REQUIRED) public void saveUser(User user) { // code } } ``` 在上述示例中,我们将 propagation 属性设置为 REQUIRED,它指示 Spring 在当前事务不存在时创建一个新事务,并在当前事务存在时使用当前事务。 @ Transactional 注解还有其他属性,例如 isolation、readOnly、timeout 等。这些属性用于控制事务的隔离级别、只读事务和超时。例如,以下是一个示例: ``` @Service public class UserServiceImpl implements UserService { @Override @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false, timeout = 10) public void saveUser(User user) { // code } } ``` 在上述示例中,我们将 isolation 属性设置为 DEFAULT,它指示 Spring 使用默认的事务隔离级别。我们将 readOnly 属性设置为 false,它指示 Spring 在事务中允许写操作。我们将 timeout 属性设置为 10,它指示 Spring 在 10 秒后将事务超时。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hamilton_Huan

原创不易,结合业务原创更不易

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值