mysql - hibernate在提交之前刷新之后获取数据

标签 mysql hibernate grails grails-orm

在我的服务类(注释为 Transactional)中,我更新对象并将其保存为:

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

此后,将进行数据处理,这需要很长时间。在此处理过程中,域类中发生了很多更改,但这些更改与此处无关。由于所有这些处理都发生在同一个服务类中,因此它是单个事务的一部分。

现在,与此同时,当所有这些处理正在进行时,另一个线程(属于不同的 hibernate session 的一部分)将访问

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

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

最佳答案

答案是,这取决于 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.

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

关于mysql - hibernate在提交之前刷新之后获取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40598149/

相关文章:

java - 引用JPA中的一个表

java - Hibernate 左外连接

Grails - 无法将子记录添加到父记录

java - "java -version"在命令提示符下不工作

mysql - 如何使用 squeryl 从表中删除所有记录?

php - 仅当 MySQL 数据库中的行等于 1 时才显示文本

php - MySQL 在 for(PHP) 循环中执行 INSERT。 INSERT 仅在第一个循环上运行

java - Hibernate 4,实现 UserType 的替代方法

mysql - 计算注册日期和首次购买日期之间的差异

grails - Controller @Mixin 仅在重新编译正在运行的应用程序后工作