【问题标题】:Spring jpa: Do I need to add @Transactional annotation on retrieval queriesSpring jpa:我需要在检索查询上添加@Transactional注释吗
【发布时间】:2021-01-22 00:46:32
【问题描述】:

我在 Spring Boot 应用程序中使用 EntityManger 进行检索查询。下面给出一个示例 sn-p。

@Repository
public class EntityManagerUtil {

  @PersistenceContext
  private EntityManager entityManager;


  public List<Employee> getAll(){

    // Use entityManager here
    
  }
}

我需要澄清以下问题。

一个。 EntityManger 是否会为每个调用创建(或)它会是一个单例吗? (我尝试打印 entityManager,它为所有调用返回相同的对象)

b.这种方法会导致任何连接泄漏吗?

c。读操作需要打@Transactional注解吗?

我使用的是spring boot 2.0.3-release版

【问题讨论】:

  • 1.这取决于您的配置,2. 否,3. 是。
  • 感谢 Denium。对于第一个问题,您能否分享一些有关我需要什么配置的信息,以及signleton entitymanager vs non-singleton ...以及为什么要在检索方法上添加@Transactional注释...如果我不这样做,有什么副作用添加
  • 假设,如果我不在检索方法上添加@Transactional注解,是否会导致任何连接泄漏或性能问题...
  • 它不会,但你想控制你的事务边界,总会有一个(隐式)事务,所以更好地控制它。 entitymanager 从来都不是单例的(你看到的是一个代理,它委托给线程绑定或事务绑定的实体管理器)。使用哪个取决于您的配置、事务设置等。

标签: spring spring-boot jpa


【解决方案1】:

a) 请参阅 M Deinum 的 cmets 关于注入的 EntityManager 作为代理。 JPA 的正常情况是将 EntityManager 绑定到每个线程,Spring 为您设置它并提供代理以委托给实际的 EntityManager。所以这种安排是安全的。

b) 当您没有将数据库连接返回到池时,会发生连接泄漏。 Spring 负责提供连接并清理资源,因此在正常情况下您不应该遇到连接泄漏。如果您忽略 Spring 为您提供的 JdbcTemplate 等设施,并坚持编写自己的 JDBC 代码,那么您可能会导致资源泄漏。如果您的代码尝试使用用于另一个线程的 EntityManager,您将收到异常,它不会静默失败,并且(本身)不会导致连接泄漏。

c) 您正在使用 RDBMS,因此您将有一个事务。 显然有些人认为交易是可选的,但实际上并非如此。如果您不指定它们,那么 Spring 会将每个操作包装在自己的事务中。一般来说,你不仅可以更好地明确这一点,而且可以将事务标记为只读,这让 Spring 可以执行一些优化,有关详细信息,请参阅Oliver Drotbohm's answer。所以也许在某些情况下你可以不使用它(例如,每个 http 请求只导致一次数据库操作),但使用它符合你的兴趣。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-27
    • 2013-01-06
    • 2015-04-16
    • 2022-01-02
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    相关资源
    最近更新 更多