0

在 Spring MVC 中,我将大多数 JPA entity(来自域层)操作放在service层下,对于大多数CRUD操作,我必须创建该服务方法或类@Transactional

但是,只是想,如果是一个常规的查找方法,就像

MyEntity myEntity = MyEntity.findByAliceAndBob(Alice alice, Bob bob);

所以问题是:

  1. 我们需要把它放在@Transactional 方法下吗?
  2. 如果没有必要,但我们仍然这样做,是否有任何性能成本?
  3. 如果没有必要,那为什么不直接将 finder 方法调用到控制器中呢?
4

2 回答 2

1

简单的答案:

我们需要把它放在@Transactional 方法下吗?

不。

如果没有必要,但我们仍然这样做,是否有任何性能成本?

是的,您正在打开一个事务并在不需要它时关闭它(请注意,对数据库的影响取决于 RDBMS 供应商)。

如果没有必要,那为什么不直接将 finder 方法调用到控制器中呢?

你可以这样做,但 IMO 你不应该这样做,因为你可能会破坏分层结构。针对您的数据源(在本例中为数据库)的操作必须在 DAO 层中完成,而不是在服务层中。

于 2013-05-02T17:45:06.920 回答
1

有很多事情促成了这个决定。

1)您使用的是开放的 entityManager 过滤器,还是处于自动提交模式?

如果您没有打开的持久性会话,那么每次在自动提交模式下执行持久性操作时,您都会从头开始构建一个全新的持久性会话,然后将其丢弃。这可以快速加起来。在这种情况下,将特定控制器所做的所有读取分组到单个事务中可能很有用,即使它“不优雅”并且破坏了 SpringMVC 提供的“漂亮”抽象。

2) 您的 JPA 方言是否支持只读事务?

@Transactional(readOnly = true)与在自动提交模式下运行查询相比,它可能是一个有用的性能提升,尤其是在加载大量实体​​的情况下。

3)你有分布式事务吗?

对于本地原子读取,联系 JTA 服务器并启动分布式事务可能不值得。

4)结果是否可能被缓存?

当您使用 Spring 声明式事务时,会出现一个问题,即 Spring 将在持久性提供者知道预期操作是什么之前获取数据库连接并启动事务。如果结果实际上位于持久性提供程序的内存中,并且不需要与数据库进行此特定操作的对话,那可能会有点浪费精力。(担心这是非常激进的微优化 IMO,如果它开始变得重要,应用服务器可能已经非常饱和了。)

于 2013-05-02T17:47:00.457 回答