繁体   English   中英

Grails:未刷新的会话和回滚的事务有什么区别?

[英]Grails: What is the difference between an unflushed session and a rolled back transaction?

我对会话和交易感到困惑。 我基本上没有看到两者兼而有之,我很困惑何时使用其中一种。

未刷新的会话和未提交的事务之间有什么区别?

我甚至不知道怎么问我不知道的...是否有一个资源可以提供常见会话和交易情况的良好示例,所以我可以看到差异?

Hibernate中的事务通常与JDBC中的事务几乎相同。 当您从DataSource获取Connection ,它默认为autocommit = true,因此对于更改为autocommit = false的事务。 这样,只有在显式提交而不是每次执行更新时,才会在数据库中进行更改。

Hibernate的Session做了几件事,但在这种情况下,它的功能是作为第一级缓存。 它使用一个名为“事务性写入后备”的概念来提高性能,以便对该缓存中的更改进行排队,并在必要时将它们推送到数据库。 因此,例如,如果您检索持久性实例并在复杂的多方法工作流中更改它,其中每个方法可能不做任何更改或几个,则只需要一个更新SQL语句,因此Hibernate会等到必要时将它们聚合在一起。 这与您是否在交易中运行无关 - 这总是会发生。

会话高速缓存和活动事务聚合在一起在活动事务期间刷新。 由于Hibernate会尽可能长时间地刷新更改,如果您不在事务中并且刷新,则更改会立即在数据库中持久化。 这是一种性能优化,可以减少数据库写入次数。 但是,如果您在事务中并刷新会话,则会将更改推送到数据库。 但是数据库会保留其事务队列中的更改。 因此,即使它们在数据库中,在您提交事务之前,它们也不会被其他连接看到。

理想情况下,不会有任何显式刷新,并且事务提交将在提交之前触发刷新,这将最大限度地减少您需要转到数据库的次数,并保持其他调用者不可见的未提交更改。 但是你可以根据需要多次冲洗。

导致Hibernate代表您自动刷新的一件事是查询。 正如我所说,你可以对持久化实例进行许多更改(甚至删除它们),它们只会在会话缓存中排队。 但是如果您运行查询(动态查找程序,条件,HQL等),Hibernate无法知道排队的更改是否会影响您的查询。 所以它是悲观的,并且要确保一切都与查询一致。 数据库将使用已刷新但未提交的查询数据并返回预期结果。 这就是我们建议您在自定义域类验证器中执行查询时使用withNewSession方法的原因,这样您就不会在验证期间导致当前会话的刷新,从而导致奇怪的行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM