Hibernate事务未能正确回滚

3

我有两个表,称为Item和Property,还有一个映射到两个表的Hibernate对象。将表Item映射到Property的映射如下

<set name="propertySet" cascade="all-delete-orphan">
    <key column="item_id" not-null="true"/>
    <one-to-many class="Property"/>
</set>

一个项目可以拥有多个属性。所有的选择、插入都正常工作。但是当出现错误时,对属性表的插入不会回滚。
问题在于,如果我正在编辑一个具有 N 个属性的项目,并在字段中输入无效值,则下一次检索该项目时,它将具有 2*N 个属性。
编辑---
我的类看起来像
@Autowired
SessionFactory sessionFactory

@Transactional
public void updateItem(Item i){
    ...
    // The only 2 statements dealing with hibernate or session in this function
    ItemModel im = sessionFactory.getCurrentSession().get(...);

    sessionFactory.getCurrentSession().update(updatedItem);
    ...
}

我正在使用Spring框架的注释式事务(@Transactional),并且最低的异常被抛出。

Caused by: org.springframework.transaction.TransactionSystemException: Could not roll back Hibernate transaction; nested exception is org.hibernate.Tra
nsactionException: Transaction not successfully started
        at org.springframework.orm.hibernate3.HibernateTransactionManager.doRollback(HibernateTransactionManager.java:679)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:845)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:822)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.java:412)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:111)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:625)
Caused by: org.hibernate.TransactionException: Transaction not successfully started
        at org.hibernate.transaction.JDBCTransaction.rollback(JDBCTransaction.java:183)
        at org.springframework.orm.hibernate3.HibernateTransactionManager.doRollback(HibernateTransactionManager.java:676)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:845)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:822)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.java:412)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:111)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:625)
    ...
    ...
        at org.apache.catalina.valves.SSLValve.invoke(SSLValve.java:113)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
        at org.apache.coyote.http11.Http11NioProcessor.process(Http11NioProcessor.java:894)
        at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:719)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:2101)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:662)
2个回答

2
在JDBC级别上,事务不会“级联”。一个事务包括以下步骤:
  1. 关闭自动提交
  2. 执行一些语句
  3. 调用java.sql.Connection.commit()java.sql.Connection.rollback()
如果你说有些东西被提交了,而有些被回滚了,那么你的事务管理出了问题。要么是自动提交开启了,要么就是你实际上有多个调用commit()的情况发生。

更新了问题以使其更清晰,并且增加了一些我在进行更多调试时遇到的异常情况。我不再调用rollback或commit,因为我假设@Transactional注释已经为我执行了这些操作。 - randomThought
正确配置后,@Transactional会建立声明式事务边界,Spring将根据需要开始、提交和回滚异常。如果您正在执行任何类似于打开会话或自己开始、提交或回滚事务的操作,那么这将会干扰。您发布的代码似乎没有任何问题,但它只是一个小片段,也不包括任何事务配置。异常表示发生了异常情况,因为Spring永远不会尝试提交/回滚未启动的事务。 - Ryan Stewart
1
你是否真正看到部分提交/回滚,还是只是在抛出异常时看到事情被提交了? 你是否意识到默认情况下受检异常不会触发回滚? - Ryan Stewart
这对我来说看起来像是自动提交已开启。请参见我的列表中的#1。如果自动提交已开启,则事务是无用的。 - Ryan Stewart
我该如何关闭它?这是我需要在MySQL实例中设置还是在Spring配置中的某个地方设置? - randomThought
显示剩余4条评论

0

如果您按照以下步骤进行操作,Spring 将在幕后管理交易:在 XML 配置中,您需要 1)启用交易,2)配置事务管理器,如下所示:

<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="mainSessionFactory" />
</bean>

Tx schemaLocation 是 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"


我在配置文件中已经有类似的内容了。 <tx:annotation-driven transaction-manager="txManager" mode='proxy' proxy-target-class='true' /> 只是bean的配置相同,唯一不同的是id='txManager'。 - randomThought

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