您应该将@Transactional放在DAO类和/或它们的方法中,还是更好地注释使用DAO对象调用的服务类?或者对两个“层”都加注释有意义吗?
当前回答
理想情况下,服务层(管理器)表示业务逻辑,因此应该用@Transactional进行注释。服务层可以调用不同的DAO来执行DB操作。让我们假设在一个服务方法中有N个DAO操作。如果您的第一个DAO操作失败,其他DAO操作可能仍然通过,您将以不一致的DB状态结束。注释服务层可以避免这种情况。
其他回答
用于数据库级别的事务
大多数情况下,我在DAO的方法级别上使用@Transactional,所以配置可以专门用于一个方法/使用默认值(必需的)
DAO获取数据的方法(select ..)-不需要 @事务性这可能会导致一些开销,因为 事务拦截器/和需要执行的AOP代理 好。 DAO的插入/更新方法将获得@Transactional
非常好的博客
应用级别: 我正在使用事务性业务逻辑,我希望能够在发生意外错误的情况下回滚
@Transactional(rollbackFor={MyApplicationException.class})
public void myMethod(){
try {
//service logic here
} catch(Throwable e) {
log.error(e)
throw new MyApplicationException(..);
}
}
传统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类型间定义将实体语义(事务和持久性)与领域对象(基本上是字段和业务方法)分离开来。
通常,应该将事务放在服务层。
但是正如前面所述,操作的原子性告诉我们哪里需要注释。因此,如果你使用像Hibernate这样的框架,其中一个“save/update/delete/…”一个对象上的“modify”操作有可能修改几个表中的几行(因为通过对象图的级联),当然在这个特定的DAO方法上也应该有事务管理。
或者对两个“层”都加注释有意义吗?-同时标注服务层和dao层不是很有意义吗-如果你想确保dao方法总是从服务层调用(传播),并且在dao中传播是“强制的”。这将为DAO方法从UI层(或控制器)调用提供一些限制。此外——特别是在对DAO层进行单元测试时——对DAO进行注释还将确保对其事务功能进行测试。
我认为事务属于服务层。它了解工作单元和用例。如果将几个dao注入到需要在单个事务中协同工作的服务中,这是正确的答案。
推荐文章
- 在流中使用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