java 如何将查询设置为未提交读取?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2015903/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to set query to be read uncommited?
提问by mrblah
with hibernate, how can I set a query to be read uncommitted? I don't want this to be a global setting, just want to do it on a per query basis.
使用休眠,如何将查询设置为未提交读取?我不希望这是一个全局设置,只想在每个查询的基础上进行。
回答by mchamati
Using Spring with Hibernate it is possible to have Spring controlling transactions with annotations, that is some configuration like the one below in spring applicationContext.xml:
将 Spring 与 Hibernate 一起使用可以让 Spring 控制带有注释的事务,这是一些类似于 spring applicationContext.xml 中的配置:
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- To use annotation driven in aspect mode (mode="aspectj"), it is necessary to add spring-aspects lib -->
<tx:annotation-driven transaction-manager="transactionManager" />
The best way to achieve that is to using an annotation like the one below:
实现这一目标的最佳方法是使用如下所示的注释:
@Transactional(propagation=Propagation.REQUIRED, isolation=Isolation.READ_UNCOMMITTED)
回答by axtavt
Have you tried session.connection().setTransactionIsolation(...)?
你试过session.connection().setTransactionIsolation(...)吗?
P.S. For modern MVCC-based DBMS you don't need to use "read uncomitted" to avoid locks. Some DBMS even don't have this isolation level implemented.
PS 对于现代基于MVCC的 DBMS,您不需要使用“未提交读取”来避免锁定。一些 DBMS 甚至没有实现这种隔离级别。
回答by Matthew Flynn
Set the transaction isolation level:
设置事务隔离级别:
session.connection().setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
回答by skaffman
The Hibernate API itself provides no way to do this programmatically, that I'm aware of. The docs do say that you can specify the isolation level as a configuration property:
据我所知,Hibernate API 本身没有提供以编程方式执行此操作的方法。文档确实说您可以将隔离级别指定为配置属性:
hibernate.connection.isolation- Sets the JDBC transaction isolation level. Check java.sql.Connection for meaningful values
hibernate.connection.isolation- 设置 JDBC 事务隔离级别。检查 java.sql.Connection 以获得有意义的值
But of course this applies to the whole SessionFactory, not just to specific queries.
但当然这适用于整体SessionFactory,而不仅仅是特定的查询。
It's tempting to fiddle with the underlying java.sql.Connectionisolation level, but I'd be very careful about doing that sort of thing, you run the risk of conflicting with hibernate's own locking strategies, which use the JDBC isolation level to determine which LockModewill be used. If you change this directly on the Connection, you might get odd results. You may not have a choice, of course, but be careful.
摆弄底层java.sql.Connection隔离级别很诱人,但我在做那种事情时会非常小心,你冒着与 hibernate 自己的锁定策略冲突的风险,这些策略使用 JDBC 隔离级别来确定LockMode将使用哪个。如果您直接在 Connection 上更改此设置,您可能会得到奇怪的结果。当然,您可能没有选择,但要小心。
A "better" solution would be to use Spring's Hibernate Transaction API, which allows you to decouple the transaction semantics like isolation level from the Hibernate API completely, in a predictable and reliable way.
“更好”的解决方案是使用Spring 的 Hibernate Transaction API,它允许您以可预测和可靠的方式将事务语义(如隔离级别)与 Hibernate API 完全分离。
回答by jspcal
by default, statements are not committed in hibernate until you do it explicitly (or the connection is returned to the pool and the driver happens to do a commit for you, which isn't guaranteed). so, it seems to do what you want already.
默认情况下,在您明确执行之前,不会在休眠中提交语句(或者连接返回到池中并且驱动程序碰巧为您执行了提交,这不能保证)。所以,它似乎已经在做你想做的事了。
you can also just rollback the current transaction if you want to nullify the statements made since the beginning of the transaction.
如果您想取消自事务开始以来所做的语句,您也可以只回滚当前事务。
in mysql, you could do something like:
在 mysql 中,您可以执行以下操作:
set session transaction isolation level read uncommitted
or use the method axtavt suggested,
或使用axtavt 建议的方法,
call getTransactionIsolation()before the query to get the current mode so you can put it back after the stmt if you like.
在查询之前调用getTransactionIsolation()以获取当前模式,以便您可以根据需要将其放回 stmt 之后。

