您应该将@Transactional放在DAO类和/或它们的方法中,还是更好地注释使用DAO对象调用的服务类?或者对两个“层”都加注释有意义吗?


当前回答

我将@Transactional放在@Service层,并设置rollbackFor任何异常和readOnly以进一步优化事务。

默认情况下@Transactional将只查找RuntimeException(未检查的异常),通过将回滚设置为exception. class(已检查的异常),它将回滚任何异常。

@Transactional(readOnly = false, rollbackFor = Exception.class)

参见已检查异常和未检查异常。

其他回答

我更喜欢在方法级的服务层上使用@Transactional。

我将@Transactional放在@Service层,并设置rollbackFor任何异常和readOnly以进一步优化事务。

默认情况下@Transactional将只查找RuntimeException(未检查的异常),通过将回滚设置为exception. class(已检查的异常),它将回滚任何异常。

@Transactional(readOnly = false, rollbackFor = Exception.class)

参见已检查异常和未检查异常。

服务层中的@事务使用是通过使用控制器层(@Controller)调用的,服务层调用DAO层(@Repository),即数据库相关的操作。

传统Spring体系结构的正确答案是将事务语义放在服务类上,原因其他人已经描述过了。

An emerging trend in Spring is toward domain-driven design (DDD). Spring Roo exemplifies the trend nicely. The idea is to make the domain object POJOs a lot richer than they are on typical Spring architectures (usually they are anemic), and in particular to put transaction and persistence semantics on the domain objects themselves. In cases where all that's needed is simple CRUD operations, the web controllers operate directly on the domain object POJOs (they're functioning as entities in this context), and there's no service tier. In cases where there's some kind of coordination needed between domain objects, you can have a service bean handle that, with @Transaction as per tradition. You can set the transaction propagation on the domain objects to something like REQUIRED so that the domain objects use any existing transactions, such as transactions that were started at the service bean.

从技术上讲,这种技术使用了AspectJ和<context:spring-configured />。Roo使用AspectJ类型间定义将实体语义(事务和持久性)与领域对象(基本上是字段和业务方法)分离开来。

服务层是添加@Transactional注释的最佳位置,因为这里呈现的大多数业务逻辑都包含细节级用例行为。

假设我们将它添加到DAO,从服务调用2个DAO类,一个失败,另一个成功,在这种情况下,如果@Transactional不在服务上,一个DB将提交,另一个DB将回滚。

因此,我的建议是明智地使用这个注释,只在服务层使用。

Github项目- java-algos