@transaction注解不起作用的原因

本文详细解析了Spring框架中@Transactional注解的使用细节与常见误区,包括其仅适用于public方法、配置需求、事务隔离级别及传播行为等核心概念。并通过实例说明了在不同场景下事务的正确与错误用法。

看似加个注解就ok了,但是实际可能就会用错了,有时候不起作用,容易被忽略。

 

1、@Transactional 注解只能应用到 public访问权限的方法上 。 如果你在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错, 但是这个被注解的方法将不起事务作用。

标注@Transactional的方法如果修饰符不是public,那么就默认方法的@Transactional信息为空,那么将不会对bean进行代理对象创建或者不会对方法进行代理调用

 

2、@Transactional 注解的使用,必须在配置文件中配置事务相关信息。(springboot不用配置)

 

3、在测试类中,

直接调用A,有事务会回滚

调用B,不会回滚。

解决方案,A和B放在不同的service里面。

因为spring事务是基于类和接口的,所以只能在类里面调用另一个类里面的事务,同一个类里面调用自己类的事务方法是无效的。

事务管理是基于动态代理对象的代理逻辑实现的,那么如果在类内部调用类内部的事务方法,这个调用事务方法的过程并不是通过代理对象来调用的,而是直接通过this对象来调用方法,绕过的代理对象,肯定就是没有代理逻辑了。

@Service
public class TestService{
  @transaction
  public void A(){
         dao.insert();
         int a = 1/0;
   }
   public void B(){
       A();
    }
}

 

 

4、自己trycatch了一下。

 

5、

B是一个事务,A新起一个事务,事实上A、B在一个事物里面。

@Service
public class TestService{
 
  @transaction(propgation = propgation.request_new)
  public void A(){
         dao.insert();
         int a = 1/0;
   }
   @transaction
   public void B(){
       A();
    }
}

 

### Spring @Transactional 注解 使用指南与常见问题 #### 1. @Transactional 注解的基本使用 @Transactional 注解是 Spring 框架中用于声明式事务管理的核心注解。它可以通过简单的配置实现对方法的事务控制,而无需编写复杂的事务管理代码。该注解可以应用于类或方法级别[^2]。 - **类级别**:当 @Transactional 应用于类时,类中的所有公共方法都将被事务管理。 - **方法级别**:推荐在方法上使用 @Transactional,以实现更细粒度的事务控制。 ```java @Service public class OrderService { @Transactional public void createOrder() { // 业务逻辑 } } ``` #### 2. 注意点:@Transactional 只能作用于公共方法 @Transactional 注解只能作用于公共方法。如果将该注解应用于私有或受保护的方法,则 Spring AOP 无法检测到这些注解,从而导致事务不起作用[^2]。 ```java // 错误示例:私有方法上的 @Transactional 不起作用 private @Transactional void updateAccount() { // 更新账户逻辑 } ``` #### 3. 自调用问题及其解决方案 在同一类中,如果一个非事务方法调用了带有 @Transactional 注解的另一个方法,事务将不会生效。这是因为 Spring AOP 使用代理机制,只有通过代理对象调用的方法才会被事务管理[^3]。 **解决方法**: - 使用 AspectJ 取代 Spring AOP 代理,以解决自调用问题[^1]。 - 或者通过显式注入当前 Bean 的代理实例来调用目标方法。 ```java @Service public class OrderService { @Autowired private OrderService self; private void insert() { self.insertOrder(); // 通过代理对象调用 } @Transactional public void insertOrder() { // 插入订单逻辑 } } ``` #### 4. 事务边界的问题 Spring AOP 在事务管理中仅检查首次进入 @Autowired 代码时的注解状态。如果一个未标注 @Transactional 的方法调用了另一个标注了 @Transactional 的方法,后者将被忽略[^2]。 ```java // 错误示例:事务边界未正确创建 public void processOrder() { saveOrder(); // 此处没有事务 } @Transactional public void saveOrder() { // 保存订单逻辑 } ``` #### 5. 编程式事务管理:TransactionTemplate 对于需要动态或复杂事务逻辑的场景,可以使用 TransactionTemplate 进行编程式事务管理[^4]。 - **execute 方法**:执行包含事务的代码块,并支持返回值。 - **executeWithoutResult 方法**:执行无返回值的事务操作。 ```java @Autowired private TransactionTemplate transactionTemplate; public User createUser(User user) { return transactionTemplate.execute(status -> { try { User newUser = userDao.save(user); return newUser; } catch (DataAccessException e) { status.setRollbackOnly(); throw new ServiceException("保存用户失败", e); } }); } ``` #### 6. DAO 层事务管理 在 DAO 层使用 @Transactional 注解时,通常需要抛出异常以触发事务回滚。例如,在 BaseDaoImpl 中,save、update 和 delete 方法均可能抛出 Exception[^5]。 ```java @Transactional public Object save(Object entity) throws Exception { getSession().save(entity); return entity; } ``` --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值