当前位置: 首页 > 面试题库 >

JPA交易如何运作

胡元忠
2023-03-14
问题内容

每当我要保留任何实体时,都会执行以下代码。看起来一切正常,但我不明白它是如何工作的!

EntityManager em = getEntityManager();
EntityTransaction userTransaction = em.getTransaction();
userTransaction.begin();
em.persist( ent );
userTransaction.commit();

上面的EntityManager是整个应用程序共享的单个实例。开始交易后;我只是说em.persist(entity)..hibernate如何知道它属于哪个事务!

假设我的应用程序上有10个并发用户,并且所有10个线程都在执行上述代码。因此,正在创建和提交10个独立的事务。但是我并没有将所有10个不同的实体与它们各自的交易相关联。那么JPA如何解决呢!

根据答案;我们有以下内容;我们是说每个线程应该有一个EntityManager实例吗?那不是杀死服务器吗?我们应该合并这些实例吗?是否等于重新实现某种类型的连接池?


问题答案:

之所以有效,是因为您足够幸运。足够幸运的是,以正确的顺序调用了commit和begin-偶然地。

您确实从多个线程使用了实体管理器的单个实例。这样做是错误的,因为不能保证它是线程安全的。通过EntityTransaction对资源级事务的访问绑定到实体管理器实例,而不是线程。

因此,结果是您共享同一个EntityTransaction,并幸运地将其连续用于多个事务。串行使用它来终止和终止多个事务是可以的,但是从多个线程使用它不是。

在hibernate(4.1.4)中,引用存储到AbstractEntityManageImpl类中的tx实例字段,但这只是实现细节。



 类似资料:
  • 我是JPA新手。我正在开发一个使用JPA(Hibernate实现)和Spring的应用程序。我在persistence.xml中声明了一个持久性单元,并在Spring配置文件中声明了有关EntityManagerFactory的配置。类似于这样: 然后我有一些DAO,我在其中注入实体管理器与@PersistenceContext注释: 最后,我有一些注入DAO的服务(通过@Autowired Sp

  • 问题内容: 我的问题基本上和这里的一样,但是我对答案不满意,所以我正在写这个问题。 在SpringFramework手册中,声明对于PROPAGATION_REQUIRES_NEW,当前事务将被挂起。实际如何实施?我知道大多数数据库不支持嵌套事务,并且在一个连接中只能运行一个事务。这意味着您不能仅仅“不使用”原始事务并启动一个新事务-在启动新事务之前,您必须提交或回滚原始事务。 例: 还是可以使用

  • 我正在学习使用JPA。我有点困惑。 根据JPA,EntityManager管理事务。但是一种设计模式是将EntityManager注入DAO中。那么不同的实体管理器怎么可能是同一个事务呢? 这是我要解决的案子 我定义了 DAO . 我有一个服务。 然后从@Controller,我将调用main Method()。在同一个服务中并使用同一个存储库中,对transactionalMED1、transa

  • 问题内容: 通常,播放!在请求成功完成后提交事务。在Play中手动提交交易的正确方法是什么? 问题答案: 您可以通过调用JPA.em()获得Hibernate EntityManager。然后,您可以从那里访问事务(JPA.em()。getTransaction())。 如果您打算自己管理事务,则将要禁用Play!的事务处理(可以在方法或控制器上使用@NoTransaction注释来执行此操作)。

  • 交易 为了与Infura节点进行交易,需要在发送它们之前离线创建交易和签名,因为Infura节点没有加密的以太坊密钥文件的访问权限,这是需要通过geth或者Parity管理命令来解锁帐户。 有关详细信息,请参阅以太坊交易中离线交易和签名部分和web3j如何使用管理APIs。

  • 交易 Web3j支持使用以太坊钱包文件(推荐的)和用于发送事务的以太坊客户端管理命令。 使用以太钱包文件发送以太币给其他人: Web3j web3 = Web3j.build(new HttpService()); // defaults to http://localhost:8545/ Credentials credentials = WalletUtils.loadCredentials