为什么JPA / Hibernate设计了一种方法来强制重新定义事务边界,即使对于一个insert / update db语句也是如此?

时间:2018-10-28 12:37:22

标签: java spring hibernate jpa transactions

到处都写着服务(或任何其他方法)对于创建的JPA持久性上下文应该是事务性的,但是我找不到任何地方可以进行这种设计。

说我想向数据库插入一行,它只是一个数据库语句,如果启用了autocommit则将是事务性的。但是突然之间,如果您使用JPA / Hibernate,则必须为JPA设置业务方法@Transactional才能创建持久性上下文并执行该单个语句。

在无JPA的世界中,我们可以有一个甚至包含多个DB语句的非事务服务方法,当然,这冒着失去整个操作的原子性的风险(这绝对是我们的选择),因此JPA为什么是设计了这样一种方式,即使该方法包含单个DB语句,该方法也迫使我们创建Transactional方法,并且无论如何该语句将在事务中使用autocommit=true执行?

4 个答案:

答案 0 :(得分:1)

我相信,即使是原子操作或非JPA案例,有关RDBMS的所有内容都将是事务性的。说到丢失数据,一切都取决于配置的isolation level。 即使您不使用任何明确的交易配置,例如通过使用JdbcTemlate或仅使用Java核心Statement,将隐式创建事务。

因此,为回答您的问题,JPA强迫使用事务使开发人员了解其行为。

在您的情况下,可能获得答案的关键词是实体的持久状态。这是nice article,说明JPA如何与实体配合使用。

答案 1 :(得分:0)

这不是与JPA相关的事情。所有数据库操作都需要一个事务,每个事务都需要一个。 事实是,有时它似乎对您隐藏了,就像您没有显式创建事务一样,底层框架会为您完成(在JPA中选择实体就是这种情况)。

总的来说,JPA不会强迫您执行,数据库会强迫您执行操作,这就是RDBMS的本质。

答案 2 :(得分:0)

此问题包含多个要点:

  1. JPA是ORM“对象关系映射”的实现,根据定义,它是将您正在使用的对象与DB上的数据双向映射,因此必须解决可熔化的问题,因此引入了事务来解决这样的问题。
  2. (仅保存一项)不是原子操作,因为您可能有2个事务在同一个字段中保存不同的数据“谈论更新以创建或添加对象,直到调用持久化之前才映射”或2个transition具有不同的脏值,因此全局上您的保存操作不是

答案 3 :(得分:0)

它与JPA不相关。它与您可能配置为工作的TransactionManager有关。一个JTA-Transactionmanager与EntityManager-Object一起将处理数据库连接,并确保在不启动事务的情况下不执行DB-Changes。

JPA-Entitymanager本身包含可用于处理事务的方法。

EntityManager-javadoc中,您将看到:

  

TransactionRequiredException-如果在类型为PersistenceContextType.TRANSACTION 的容器管理的实体管理器上调用时没有事务

因此,您一看到使用TransactionManager,就会看到Entitymanager得到容器管理。

另请参阅:Container Managed Entitymanager