您应该将@Transactional放在DAO类和/或它们的方法中,还是更好地注释使用DAO对象调用的服务类?或者对两个“层”都加注释有意义吗?
当前回答
我将@Transactional放在@Service层,并设置rollbackFor任何异常和readOnly以进一步优化事务。
默认情况下@Transactional将只查找RuntimeException(未检查的异常),通过将回滚设置为exception. class(已检查的异常),它将回滚任何异常。
@Transactional(readOnly = false, rollbackFor = Exception.class)
参见已检查异常和未检查异常。
其他回答
我认为事务属于服务层。它了解工作单元和用例。如果将几个dao注入到需要在单个事务中协同工作的服务中,这是正确的答案。
服务层中的@事务使用是通过使用控制器层(@Controller)调用的,服务层调用DAO层(@Repository),即数据库相关的操作。
通常情况下是在服务层级别上注释,但这实际上取决于您的需求。
在服务层上注释将比在DAO层上注释产生更长的事务。这取决于事务隔离级别,可以产生问题,因为并发事务不会看到彼此的更改,例如。可重复读。
在dao上注释将使事务尽可能简短,缺点是您的服务层公开的功能不会在单个(可回滚的)事务中完成。
如果传播模式被设置为默认,那么对两个层都进行注释就没有意义了。
传统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可能会降低方法性能。 为了了解全局,您必须了解事务隔离级别。了解这一点可以帮助您避免在不必要的地方使用@Transactional。
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap