Grails:未刷新的会话和回滚事务有什么区别? [英] Grails: What is the difference between an unflushed session and a rolled back transaction?

查看:123
本文介绍了Grails:未刷新的会话和回滚事务有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很困惑会议和交易。我基本上没有看到两者有什么不同,而且我很困惑什么时候使用其中一种。



未刷新的会话有什么区别和一个未提交的交易?



我甚至不知道怎么问什么我不知道......是否有一个资源提供了常见会话的好例子,事务情况,所以我可以看到它们之间的区别吗?

解决方案

Hibernate中的事务几乎与JDBC中的事务相同。当你从 DataSource 获取 Connection 时,它默认为autocommit = true,所以对于更改为autocommit =假。这种方式只会在显式提交时才会在数据库中进行更改,而不是每次执行更新。


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



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



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

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


I am SO confused by sessions and transactions. I basically don't see what the point of having both is, and I am very confused when to use one or the other.

What is the difference between an unflushed session and an uncommitted transaction?

I don't even know how to ask what I don't know... is there a resource that gives good examples of common session and transaction situations so I can see the difference?

解决方案

A transaction in Hibernate is pretty much the same as a transaction in JDBC in general. When you get the Connection from the DataSource it defaults to autocommit=true, so for the transaction that's changed to autocommit=false. That way changes get made in the database only when explicitly committed instead of each time you do an update.

Hibernate's Session does several things but in this case its function is as the 1st-level cache. It uses a concept called "transactional writebehind" for performance to queue up changes in that cache and only push them to the database when necessary. So for example if you retrieve a persistent instance and change it in a complex multi-method workflow where each method possibly makes no changes or several, only one update SQL statement is needed so Hibernate waits until necessary to aggregate them together. This is independent of whether you're running in a transaction though - that always happens.

Where the session cache and active transaction get together is flushing during an active transaction. Since Hibernate waits as long as possible to flush changes, if you're not in a transaction and you flush, the changes become persistent in the database immediately. So that's a performance optimization to reduce the number of database writes. But if you are in a transaction and you flush the session, you do push the changes to the database. But the database keeps the changes in its transaction queue. So even though they're in the database, they're not visible to other connections until you commit the transaction.

Ideally there won't be any explicit flushes, and the transaction commit will trigger a flush before the commit and that will both minimize the number of times you need to go to the database and keep uncommitted changes invisible to other callers. But you can flush as many times as you need.

One thing that will cause Hibernate to flush automatically on your behalf is queries. As I said you can make many changes to persistent instances (even deleting them) and they'll just be queued up in the session cache. But if you run a query (a dynamic finder, criteria, HQL, etc.) Hibernate can't know if the queued changes will affect your query. So it's pessimistic and flushes to be sure that everything's consistent for the query. The database will use the flushed but not committed data for your query and return the expected results. This is the reason we recommend that you use the withNewSession method when doing queries in custom domain class validators so you don't cause a flush of the current session during validation which can cause weird behavior.

这篇关于Grails:未刷新的会话和回滚事务有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆