提交前刷新后休眠获取数据

hibernate get data after flush before commit

在我的服务 class(注释为事务性)中,我更新对象并将其另存为:

myObj.save(flush:true)   //(Thread A, updates the value, Step A)

在此之后,需要很长时间才能处理数据。在此处理期间,在域 classes 中进行了大量更改,但这些更改与此处无关。由于所有这些处理都发生在同一个服务中 class,它是单个事务的一部分。

现在,与此同时,当所有这些处理都在进行时,属于不同休眠会话的另一个线程访问

MyObj.findAll() //Thread B 并且在结果集中我看到了更新后的值。在 Step A 中更新的值 但是,线程 A 尚未完成,因此更改尚未提交到数据库。我可以确认这一点,因为同时如果我 运行 直接在 mysql workbench 中查询,那么我看不到更改。更改仅在通过休眠访问对象时可见。

我的印象是,如果由于刷新而进行更改,那么这些更改在同一事务中是可见的,而不是在其他事务中。有人可以澄清一下吗?

答案是,这取决于 mysql 服务器中使用的隔离级别。正如 mysql 关于 innodb transaction isolation levels 的文档所说:

the isolation level is the setting that fine-tunes the balance between performance and reliability, consistency, and reproducibility of results when multiple transactions are making changes and performing queries at the same time.

InnoDB offers all four transaction isolation levels described by the SQL:1992 standard: READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, and SERIALIZABLE. The default isolation level for InnoDB is REPEATABLE READ.

文档非常详细地描述了各个级别之间的差异。我想特别提请您注意未提交的读取级别:

SELECT statements are performed in a nonlocking fashion, but a possible earlier version of a row might be used. Thus, using this isolation level, such reads are not consistent. This is also called a dirty read. Otherwise, this isolation level works like READ COMMITTED.

此隔离级别使查询能够读取由尚未提交的其他事务更新的数据。但是,在您的代码中使用此隔离级别之前,请确保您了解此隔离级别的所有含义。您无法挑选要查看哪些事务的未提交数据。因此,您可以选择稍等片刻来获取提交的数据。