数据库中的Hibernate查询

5

我在使用Hibernate查询数据库时遇到了问题,它执行的查询数量过多。这是我的查询日志(使用Mysql 5.1):

111125  7:18:30
27 Query    SET autocommit=0
27 Query    SELECT @@session.tx_isolation
27 Query    select this_.id as id34_0_, this_.media_id as media3_34_0_, this_.message as message34_0_, this_.user_id as user4_34_0_ from notifications this_
27 Query    rollback
27 Query    SET autocommit=1

我已经阅读了很多关于将autocommit设置为0然后设置为1的内容。我知道连接的默认值是1,这种行为无法更改。你可以运行SET autocommit = 0,但结果是相同的。
有没有办法避免这些查询中的任何一项?我不知道为什么会发生SELECT @@session.tx_isolation和回滚。当我使用事务时,我得到一个提交然后回滚。不确定为什么总是会回滚。
非常感谢!
我的配置: Spring 2.5.6,Hibernate 3.6.0,Mysql 5.1
datasoure.xml:
<bean id="dataSource" destroy-method="close"
    class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />

    <property name="initialSize" value="3" />
    <property name="maxActive" value="20" />
    <property name="minIdle" value="3" />
    <property name="poolPreparedStatements" value="false" />
    <property name="defaultAutoCommit" value="false" />
    <property name="defaultTransactionIsolation" value="4" />
</bean>

事务管理器定义:

<bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

更新:通过设置新属性,成功取消了回滚。

<property name="defaultReadOnly" value="true" />

但现在的问题是,无论我是否将事务注解设置为readOnly=false,都无法对数据库进行修改,会出现SQLException。

这个属性将连接设置为只读模式。

我猜想在HibernateTemplate中没有办法实现这一点。

我使用aspectj事务进行内部代码织入。

<aop:aspectj-autoproxy proxy-target-class="true" />

你的事务失败了!你在Spring上下文中启用了事务管理器吗?而且你的日志是正常的,我的也类似,除了回滚。 - madhead
这只是一个选择操作,并没有@transactional注释。似乎所有的操作都被视为事务处理。 - Gonzalo
我是指本地数据库级别:27个查询回滚。它会回滚事务。你的插入或更新是否正常工作? - madhead
是的,当我在方法中使用 @Transactional 时,如果抛出异常,它会转为提交或回滚。因此,在事务上的插入、更新和选择操作都可以正常工作。我认为在每个“简单”的选择操作上进行回滚,可能会增加一些额外开销。 - Gonzalo
1个回答

1

您需要为应用程序配置事务。请参阅Spring 2.5.x事务管理文档

编辑12/3/11:即使是仅执行选择操作的方法,您仍然需要创建一个只读事务,以便删除您在帖子中提到的额外查询。只需编写@Transactional(readOnly=true),您就可以开始了。

编辑12/20/11:您还需要确保正确配置了事务。看起来您发布的配置可能缺少注释。请参阅Spring文档第10.5.1节


我已经添加了事务管理器。当我需要一个事务时,我使用@transactional注释,但在这种情况下,没有进行任何事务。 - Gonzalo
即使是仅执行查询的方法,您仍然需要创建一个只读事务,以便消除您在帖子中提到的额外查询。只需编写 @Transactional(readOnly=true) 即可。 - Matt Sgarlata
仍然出现相同的事务回滚和自动提交。现在即使readonly=true,我也会得到一个提交。 - Gonzalo
请查看我的更新回复:您还需要确保事务配置正确。看起来您发布的配置可能缺少tx:annotation-driven/注释。请参阅Spring文档的第10.5.1节。 - Matt Sgarlata
我使用aspectj事务。请查看我的帖子的最后一部分。事务运行得非常完美,唯一的问题是查询量太大。我发现如果与数据库的连接是只读的,则回滚不会发生。但这对于事务的只读标志永远不重要。我认为这只是让Hibernate不检查对象和集合是否脏数据。 - Gonzalo
有些不对劲。或者你的事务配置没有按照你想的那样工作,或者你在小方法上指定了事务,而没有在包含应该在事务中的所有内容的更大的整体方法上指定。你应该尝试以下两种方式:1. 尝试使用 tx:annotation-driven/ 而不是 AspectJ 看看是否有区别;2. 尝试将 @Transactional 注释移到更高级别的方法中,比如网页控制器内部,而不是低级别DAO中。 - Matt Sgarlata

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接