【发布时间】:2010-01-06 20:18:23
【问题描述】:
使用hibernate,我如何设置一个未提交的查询? 我不希望这是一个全局设置,只想在每个查询的基础上进行。
【问题讨论】:
-
您是手动管理事务,还是使用 sprig/EJB
-
这听起来像是过早的优化(这是万恶之源)。您目前有真正的问题吗?
标签: java hibernate transactions
使用hibernate,我如何设置一个未提交的查询? 我不希望这是一个全局设置,只想在每个查询的基础上进行。
【问题讨论】:
标签: java hibernate transactions
将 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" />
实现这一点的最佳方法是使用如下注释:
@Transactional(propagation=Propagation.REQUIRED, isolation=Isolation.READ_UNCOMMITTED)
【讨论】:
设置事务隔离级别:
session.connection().setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
【讨论】:
你试过session.connection().setTransactionIsolation(...)吗?
附:对于现代MVCC-based DBMS,您不需要使用“read uncommitted”来避免锁定。一些 DBMS 甚至没有实现这个隔离级别。
【讨论】:
据我所知,Hibernate API 本身无法以编程方式执行此操作。文档确实说您可以将隔离级别指定为配置属性:
hibernate.connection.isolation - 集 JDBC 事务隔离级别。 检查 java.sql.Connection 有意义的价值观
但这当然适用于整个SessionFactory,而不仅仅是特定的查询。
很容易摆弄底层的java.sql.Connection 隔离级别,但我会非常小心地做那种事情,你冒着与 hibernate 自己的锁定策略冲突的风险,它使用 JDBC 隔离级别来确定其中LockMode 将被使用。如果您直接在 Connection 上更改它,您可能会得到奇怪的结果。当然,你可能别无选择,但要小心。
“更好”的解决方案是使用Spring's Hibernate Transaction API,它允许您以可预测且可靠的方式将隔离级别等事务语义与 Hibernate API 完全分离。
【讨论】:
默认情况下,在您明确执行之前,语句不会在休眠状态下提交(或者连接返回到池中并且驱动程序恰好为您执行了提交,这是无法保证的)。所以,它似乎已经在做你想做的事了。
如果您想取消自事务开始以来所做的语句,您也可以只回滚当前事务。
在 mysql 中,你可以这样做:
set session transaction isolation level read uncommitted
或者使用axtavt suggested的方法,
在查询之前调用getTransactionIsolation() 以获取当前模式,以便您可以根据需要在stmt 之后将其放回。
【讨论】: