事务似乎已回滚,但它们并未在数据库中回滚

Posted

技术标签:

【中文标题】事务似乎已回滚,但它们并未在数据库中回滚【英文标题】:Transactions appear to be rolled back, but they are not rolled back in the database 【发布时间】:2012-07-13 17:37:45 【问题描述】:

PersistenceHelper-context.xml

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">    <!---->
        <property name="driverClassName" value="org.hsqldb.jdbc.JDBCDriver"/>
        <property name="url" value="jdbc:hsqldb:mem:mydb"/>
        <property name="username" value="sa"/>
        <property name="password" value=""/>
    </bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
          depends-on="dataSource" name="_sessFac" >  
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="hibernate.cfg.xml.incDTD"/>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.connection.shutdown">true</prop>
            </props>
        </property>
    </bean>

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

类头

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:PersistenceHelper-context.xml")
@TransactionConfiguration(defaultRollback = true, transactionManager = "transactionManager") 
@Transactional
public class BaseClass extends BaseTestClass//.....

然后我想要使用事务的所有类都派生自 BaseClass,即 public class FooTest extends BaseClass

另外,当我运行我的代码时,我会看到以下内容:

HibernateTransactionManager | Initiating transaction rollback
[13 Jul 2012 11:29:13,738] DEBUG  HibernateTransactionManager | Rolling back Hibernate transaction on Session [org.hibernate.impl.SessionImpl@107536b]
[13 Jul 2012 11:29:13,738] DEBUG  HibernateTransactionManager | Triggering afterCompletion synchronization
[13 Jul 2012 11:29:13,738] DEBUG  TransactionSynchronizationManager | Clearing transaction synchronization
[13 Jul 2012 11:29:13,738] DEBUG  TransactionSynchronizationManager | Removed value [org.springframework.orm.hibernate3.SessionHolder@17b3cdb] for key [org.hibernate.impl.SessionFactoryImpl@14642ac] from thread [main]
[13 Jul 2012 11:29:13,738] DEBUG  TransactionSynchronizationManager | Removed value [org.springframework.jdbc.datasource.ConnectionHolder@129a6a3] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@c506b] from thread [main]
[13 Jul 2012 11:29:13,738] DEBUG  HibernateTransactionManager | Closing Hibernate Session [org.hibernate.impl.SessionImpl@107536b] after transaction
[13 Jul 2012 11:29:13,738] DEBUG  SessionFactoryUtils       | Closing Hibernate Session
[13 Jul 2012 11:29:13,738] INFO   TransactionalTestExecutionListener | Rolled back transaction after test execution for test context

然而,当我从我的数据库中删除时,更改会保留下来,并且我未来的测试会失败,因为表中缺少一个对象。我错过了什么吗?任何方向将不胜感激。提前致谢!!

【问题讨论】:

如何获取 Hibernate 会话?您确定您使用的会话是事务回滚的会话吗? 你确定hsqldb支持事务吗?并非每个数据库都支持它们。例如,mysql 在使用 MyISAM 存储引擎表时不支持事务,仅支持 InnoDB 和 BDB。检查 hsql 文档。 HSQLDB 支持事务。经常建议使用 Spring/Hibernate 对应用程序进行单元/集成测试。 Session session = _sessFac.openSession(); 然而,我为每个@Test 获取了一个新会话。虽然我认为这是合法的,因为类顶部的 @Transactional 注释包装了事务中的每个方法。 是的。HSQLDB 商业用户的商业支持可从 ... 它提供一个小型、快速的多线程和 事务性 数据库引擎-内存... 【参考方案1】:

您应该使用sessionFactory.getCurrentSession() 来获取与当前事务关联的Session

openSession() 创建一个新会话,该会话与 Spring 管理的事务无关。

【讨论】:

这可能已经完成了。。还有一些东西要弄清楚,如果是这样,我会接受。【参考方案2】:

我从未使用过 DriverManagerDataSource,但我认为它可以将某种“autoCommit”属性默认设置为 true。您可以尝试使用真正的连接池,如c3p0(因为 DriverManagerDataSource 类不是实际的连接池)。有了它,我的交易没有任何问题。

【讨论】:

以上是关于事务似乎已回滚,但它们并未在数据库中回滚的主要内容,如果未能解决你的问题,请参考以下文章

SQL0911N 由于死锁或超时,已回滚当前事务。原因码“68”。SQLSTATE=40001

事务未在春季批处理项目编写器中回滚

事务无法在 codeigniter 中回滚

无法访问 SqlTransaction 对象以在 catch 块中回滚

有没有办法在 Quarkus 单元测试中回滚事务?

PostgreSQL:在 plpgsql 函数中回滚事务?