Spring @Transactional注解类或方法

6
尝试收集和理解@Transactional注释的主要要点,并跨越了一个重点。因此,使用Transactional注释时需要牢记以下几点:
  1. Transactional注释只能应用于公共方法[根据Spring @Transactional属性适用于私有方法吗?]。
  2. Transactional注释应该应用于具体类而不是接口[根据在接口定义或实现类中放置@Transactional注释怎么办?]。
  3. Transactional注释应该在服务层上应用[根据Spring @Transactional注释最佳实践]。
  4. 如果您想要将整个类注释为事务,但要排除某些公共方法,则可以使用一些传播策略[根据注释整个类+排除单个方法中的Transactional注释]。

不幸的是,我没有找到答案:将Transactional注释放在类还是方法中更好?我们可以考虑不同的情况,但我大多数时间都对必须具有此注释的几种方法以及某些方法不感兴趣。

另外,如果您想将一些要点添加到此列表中,那就太好了。


2
1 已经不再是真实的了,而且已经有一段时间了。如果您使用Spring的编织支持(编译时或加载时),则注释可以放在 任何 方法上。 - Boris the Spider
如果您的某些方法不需要注释,那么如果我理解正确,您根本不需要事务。所以,如果您已经在类中声明了事务,为什么还要通过注释来打开一个事务呢?我建议只在需要事务的所有方法上编写该注释。 - Jan
@BoristheSpider,这是一个有趣的事实,谢谢。 - Rufi
@Jan,这就是问题所在。如果我有很多需要事务处理的方法,如果我将我的事务注释放到所有这些方法而不是类中,我感觉这是重复的代码。我只是猜测,即使一些其他方法不需要事务处理,将其放入类中是否不好。 - Rufi
在这种情况下,代码重复并不重要。在我看来,在您的情况下,事务不应被视为横切关注点,因为有时它们是不必要的。更一般地说,我总是避免在类级别上使用事务注释,并定义执行所需操作的方法,这将有利于关注点的清晰分离和可测试性。 - Raffaele
2个回答

3
这里是我能想到的优点(以及隐含的缺点)列表。
方法级别的优点:
- 易于阅读:您可以查看一个方法并且不必查看类、实现的接口或超类就可以确定它是否具有事务性。 - 明确:注释清楚地告诉您该方法是“意味着”具有事务性。它不仅仅因为类中的所有方法都具有事务性而具有事务性。 - 减少无意合并独立事务:如果您从(隐含)事务性方法调用多个事务性方法,则外部事务定义整个事务(除非传播设置像REQUIRES_NEW之类)。虽然在许多情况下这不是问题,但我曾见过项目由于长期而陷入严重麻烦。特别是当涉及悲观锁定时,将事务保持独立和小型非常关键,因此事务仅需要少量锁,并且尽快释放锁。
类级别的优点:
- 减少重复:如果您在类级别上放置注释,则不必注释每个事务性方法。有些人认为在每个事务性方法上放置注释违反了DRY原则。但是,依我之见,如果这违反了DRY原则,那么Java的private/protected/public修饰符也是如此。

1
如果我们将事务放在类级别而不是方法级别,是否会出现性能相关问题? - Mital Pritmani

2
在我看来,最好是单独为每个方法标记@Transactional注解(以指示该方法正在更新某些内容),而不是标记整个类。这会产生更多的代码,并且在某些情况下可能会重复,但想象一下你的服务中有10个方法,其中9个方法正在更新某些内容,而只有一个方法是只读的。您的代码正在使用ORM(例如Hibernate),并且您的方法中有一些由Hibernate管理的对象。在添加新逻辑时,您意外更改了Hibernate管理的对象中的一个字段。在这种情况下,Hibernate将在应该只读的方法中触发更新SQL指令。这可能会产生难以发现的错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接