Hibernate Grails:未刷新会话和回滚事务之间的区别是什么?

Hibernate Grails:未刷新会话和回滚事务之间的区别是什么?,hibernate,session,grails,transactions,gorm,Hibernate,Session,Grails,Transactions,Gorm,我被会话和事务弄糊涂了。我基本上不明白两者都有什么意义,我很困惑什么时候用一个或另一个 未刷新的会话和未提交的事务之间有什么区别 我甚至不知道怎么问我不知道的事。。。是否有一个资源提供了常见会话和事务情况的良好示例,以便我能够看到它们之间的区别?Hibernate中的事务与JDBC中的事务大体相同。从数据源获取连接时,它默认为autocommit=true,因此对于更改为autocommit=false的事务。这样,只有在显式提交时才在数据库中进行更改,而不是每次更新时 Hibernate的会话

我被会话和事务弄糊涂了。我基本上不明白两者都有什么意义,我很困惑什么时候用一个或另一个

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


我甚至不知道怎么问我不知道的事。。。是否有一个资源提供了常见会话和事务情况的良好示例,以便我能够看到它们之间的区别?

Hibernate中的事务与JDBC中的事务大体相同。从
数据源
获取
连接时,它默认为autocommit=true,因此对于更改为autocommit=false的事务。这样,只有在显式提交时才在数据库中进行更改,而不是每次更新时

Hibernate的
会话
做了几件事,但在本例中,它的功能是作为一级缓存。为了提高性能,它使用了一个名为“transactional writebehind”的概念,将缓存中的更改排队,并仅在必要时将其推送到数据库。因此,例如,如果您检索一个持久实例并在一个复杂的多方法工作流中对其进行更改,其中每个方法可能不进行任何更改或多次更改,则只需要一条update SQL语句,因此Hibernate会等到需要时才将它们聚合在一起。不过,这与您是否在事务中运行无关——这总是发生的

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

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

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