在我的服务类(注释为Transactional)中,我更新然后将对象保存为:
myObj.save(flush:true) //(Thread A, updates the value, Step A)
此后,数据处理需要很长时间。在此处理过程中,域类中进行了大量更改,但这些更改与此处无关。由于所有这些处理都发生在同一个服务类中,因此它是单个事务的一部分。
现在,与此同时,当所有这些处理都在进行时,另一个线程,它是不同的hibernate会话的一部分,访问
MyObj.findAll() //Thread B
在结果集中,我看到了更新后的值。在Step A
中更新的值但是,线程A尚未完成,因此更改尚未提交到数据库。我可以确认这一点,因为同时如果我直接在mysql工作台中运行查询,那么我没有看到更改。仅当通过休眠访问对象时才会显示更改。
我的印象是,如果由于刷新而进行了更改,那么这些更改在同一事务中可见,而在其他事务中则不可见。请有人澄清一下吗?
答案 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。
此隔离级别使查询能够读取尚未提交的其他事务更新的数据。但是,在代码中使用此隔离级别之前,请确保您了解此隔离级别的所有含义。您无法挑选出您想要查看的未交换数据的交易。因此,您可以选择等待一段时间以获取提交的数据。