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

时间:2016-11-14 21:30:43

标签: mysql hibernate grails gorm

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

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

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

现在,与此同时,当所有这些处理都在进行时,另一个线程,它是不同的hibernate会话的一部分,访问

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

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

1 个答案:

答案 0 :(得分:1)

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

  

隔离级别是微调其间平衡的设置   性能和可靠性,一致性和可重复性   多个事务进行更改和执行时的结果   同时查询。

     

InnoDB提供了所描述的所有四种事务隔离级别   SQL:1992标准:READ UNCOMMITTED,READ COMMITTED,REPEATABLE READ,   和SERIALIZABLE。 InnoDB的默认隔离级别是REPEATABLE   READ。

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

  

SELECT语句以非锁定方式执行,但是a   可能会使用行的早期版本。因此,使用这个   隔离级别,这种读取不一致。这也称为a   脏读。否则,此隔离级别的作用类似于READ COMMITTED。

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