您应该将@Transactional放在DAO类和/或它们的方法中,还是更好地注释使用DAO对象调用的服务类?或者对两个“层”都加注释有意义吗?
当前回答
服务层中的@事务使用是通过使用控制器层(@Controller)调用的,服务层调用DAO层(@Repository),即数据库相关的操作。
其他回答
最好将@Transactional放在DAO和服务层之间的单独中间层中。 由于回滚非常重要,您可以将所有的DB操作放在中间层,并在服务层中编写业务逻辑。中间层将与DAO层交互。
这将帮助您在许多情况下,如ObjectOptimisticLockingFailureException -此异常只发生在您的事务结束后。所以,你不能在中间层捕获它,但你现在可以在服务层捕获它。如果在服务层中有@Transactional,这是不可能的。虽然你可以在控制器中捕获,但控制器应该尽可能干净。
如果您在完成所有保存、删除和更新选项后在单独的线程中发送邮件或短信,您可以在中间层事务完成后在服务中执行此操作。同样,如果你在服务层提到@Transactional,即使你的事务失败,你的邮件也会被发送。
所以有一个中间的@Transaction层将有助于使你的代码更好,更容易处理。否则, 如果在DAO层使用,可能无法回滚所有操作。 如果在服务层使用,在某些情况下可能必须使用AOP(面向方面编程)。
此外,Spring建议只在具体的类上使用注释,而不是在接口上使用。
http://static.springsource.org/spring/docs/2.0.x/reference/transaction.html
通常,应该将事务放在服务层。
但是正如前面所述,操作的原子性告诉我们哪里需要注释。因此,如果你使用像Hibernate这样的框架,其中一个“save/update/delete/…”一个对象上的“modify”操作有可能修改几个表中的几行(因为通过对象图的级联),当然在这个特定的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类型间定义将实体语义(事务和持久性)与领域对象(基本上是字段和业务方法)分离开来。
推荐文章
- 如何分割逗号分隔的字符串?
- Java字符串—查看字符串是否只包含数字而不包含字母
- Mockito.any()传递带有泛型的接口
- 在IntelliJ 10.5中运行测试时,出现“NoSuchMethodError: org.hamcrest. matcher . descripbemismatch”
- 使用String.split()和多个分隔符
- Java数组有最大大小吗?
- 在Android中将字符串转换为Uri
- 从JSON生成Java类?
- 为什么java.util.Set没有get(int index)?
- Swing和AWT的区别是什么?
- 为什么Java流是一次性的?
- 四舍五入BigDecimal *总是*有两位小数点后
- 设计模式:工厂vs工厂方法vs抽象工厂
- Java:检查enum是否包含给定的字符串?
- 它的意思是:序列化类没有声明一个静态的最终serialVersionUID字段?