ivan_070 2024-07-31 20:56 采纳率: 100%
浏览 11
已结题

@Transactional能否通过内部类实现

同一个类中方法A中没有事务,调用有事务的方法B无法生效。我在网上看了很多解决办法,都不太好,因为我的项目中实例化的都是Service的接口,使用代理对象调用的话就需要在接口上创建一个方法,这样等于把这个方法暴露出去了。
所以我想在service中创建一个内部类来实现。测试后事务是起作用了,但是我不知道这样有没问题,所以想请大家帮忙看看

public interface IUserService{
    void m1();
}


@Service
public class UserServiceImpl implements IUserService {

    @Autowired
    @Lazy
    private SubService subService;

    @Override
    public void m1() {
        subService.test();
    }


    @Service
    class SubService{
        @Transactional(rollbackFor = Throwable.class)
        public void test(){
            //更新数据库
            //抛出异常,然后事务成功回滚
        }
    }
}


在controller中调用m1方法,数据库没有更新,确实回滚成功了。
我想问问,这种内部类的方式来实现事务是否可行

  • 写回答

3条回答 默认 最新

  • 西可我偏偏是这款 2024-07-31 22:06
    关注

    在Spring Boot中,@Transactional 注解用于声明事务性操作。它通常应用于服务类的方法上,以确保方法中的操作在同一个事务中执行。@Transactional 通常使用在公开的方法上,因为 Spring 的事务管理是基于代理的,代理会拦截对方法的调用以处理事务。
    内部类的事务管理可以相对复杂一些,尤其是如果你希望在内部类中使用 @Transactional。下面是几个要点,帮助理解如何在内部类中使用事务:

    1. 内部类的事务支持
      Spring 的事务管理是基于代理的,这意味着事务注解的处理依赖于 Spring 的 AOP(面向切面编程)。事务代理通常作用于类的公开方法。如果在一个内部类中使用 @Transactional,你可能会遇到以下问题:
      外部类中的事务:如果你希望在内部类中使用事务,你需要确保外部类的事务配置和上下文已经正确配置,并且事务管理器能够识别到内部类的事务要求。
      代理问题:内部类的方法通常不能被代理,特别是当内部类是非静态的时,这意味着 Spring 可能无法创建代理来处理事务。
    2. 静态内部类的事务
      对于静态内部类,事务管理相对简单,因为静态内部类的事务是独立的,不会受到外部类实例的限制。这种情况下,你可以直接在静态内部类的方法上使用 @Transactional。
    3. 使用外部类的事务
      一种常见的实践是在外部类中管理事务,并通过公开的方法调用内部类的逻辑。这样,你可以利用 Spring 的事务管理来控制整个业务流程。
    4. 自定义事务管理
      如果需要在内部类中使用事务,你可以考虑自定义事务管理,手动创建事务管理器,控制事务的开始和提交。这种方法较为复杂,通常不推荐作为首选方案。
      结论:
       直接在非静态内部类中使用 @Transactional 通常是不推荐的,因为 Spring 的事务管理基于代理,代理不能处理非静态内部类的方法。建议使用外部类或静态内部类来处理事务,或者将事务逻辑放在公开的方法中,以确保事务管理的正确性和一致性。如果需要在内部类中处理事务,考虑将事务处理放在外部类中,并通过公开的方法调用内部类逻辑。
      
      在上述示例中,outerMethod 由 @Transactional 注解修饰,确保了事务的开始和提交。然后在 outerMethod 内部,创建了 InnerService 的实例并调用了 innerMethod。这种方式能够保证事务的一致性和完整性。
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 8月10日
  • 已采纳回答 8月2日
  • 创建了问题 7月31日

悬赏问题

  • ¥15 编一个判断一个区间范围内的数字的个位数的立方和是否等于其本身的程序在输入第1组数据后卡住了(语言-c语言)
  • ¥15 游戏盾如何溯源服务器真实ip?
  • ¥15 Mac版Fiddler Everywhere4.0.1提示强制更新
  • ¥15 android 集成sentry上报时报错。
  • ¥50 win10链接MySQL
  • ¥35 跳过我的世界插件ip验证
  • ¥15 抖音看过的视频,缓存在哪个文件
  • ¥15 自定义损失函数报输入参数的数目不足
  • ¥15 如果我想学习C大家有是的的资料吗
  • ¥15 根据文件名称对文件进行排序