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

Mik*_*key 10 session grails hibernate transactions grails-orm

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

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

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

Bur*_*ith 22

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

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

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

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

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