2012-10-03 26 views
1

我已经创建了完成后未回滚事务的服务的集成测试。我通过查看数据库和从第二次运行测试时得到的错误中知道这一点。我一直在使用googling这个问题,并感觉我已经正确设置了一切。这是一个写入SQLServer 2008的hibernate/jpa应用程序。我不确定在哪里可以看。下面的代码段。Junit测试不回滚sqlserver上的事务

@RunWith(SpringJUnit4ClassRunner.class) 
@TestExecutionListeners({ 
     DependencyInjectionTestExecutionListener.class, 
     DirtiesContextTestExecutionListener.class, 
     TransactionalTestExecutionListener.class }) 
@TransactionConfiguration(defaultRollback=true) 
@Transactional // extend transactional boundary to test class so that automatic rollback works properly 
@ContextConfiguration(locations = { 
     "file:./src/main/resources/AghostMobile.Service-business.service-context.xml", 
     "file:./src/main/resources/AghostMobile.Service-service-context.xml", 
     "file:./src/main/resources/AghostMobile.Service-dao-context.xml"}) 
public class ColorSchemeMigrationServiceIntTest { 

    /** 
    * The service being tested, injected by Spring 
    * 
    */ 
    @Autowired 
    ColorSchemeMigrationService service; 

    /** 
    * The helper services, injected by Spring. 
    * 
    */ 
    @Autowired 
    protected WebsitecolorpaletteuserdefinedService userPaletteService; 
    @Test 
    public void testSaveColorPalette() { 
     Integer mobileWebsiteId = Integer.valueOf(386); 
     Integer custId = Integer.valueOf(15); 
     Integer siteId = Integer.valueOf(2); 
     String user = "Test"; 

     Websitecolorpaletteuserdefined palette = service.translateColorScheme(mobileWebsiteId, custId, siteId, user); 

     service.saveColorPalette(palette); 

     Websitecolorpaletteuserdefined response = userPaletteService.findWebsitecolorpaletteuserdefinedByCustIdAndSiteId(custId, siteId); 

     assertNotNull("User palette not found.", response); 
     assertEquals("CustId is not the expected value.", custId, response.getCustId()); 
     assertEquals("SiteId is not the expected value.", siteId, response.getSiteId()); 
    } 

目前,我有以下豆定义:

<!-- ******************************************************************** --> 
<!-- Setup the transaction manager --> 
<!-- ******************************************************************** --> 
    <!-- Using Atomikos Transaction Manager --> 
    <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" 
     destroy-method="close"> 
     <property name="forceShutdown" value="true" /> 
     <property name="startupTransactionService" value="true" /> 
     <property name="transactionTimeout" value="60" /> 
    </bean> 

    <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp" /> 
    <!-- Configure the Spring framework to use JTA transactions from Atomikos --> 
    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> 
     <property name="transactionManager" ref="atomikosTransactionManager" /> 
     <property name="userTransaction" ref="atomikosUserTransaction" /> 
     <property name="transactionSynchronizationName" value="SYNCHRONIZATION_ON_ACTUAL_TRANSACTION" /> 
    </bean> 
<!-- ******************************************************************** --> 
<!-- Setup a data source --> 
<!-- ******************************************************************** --> 
<!-- Using Apache DBCP Data Sources --> 
<bean name="hostDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" > 
    <property name="driverClassName" value="${My_JDTs_to_AgHost_Host_scheme.connection.driver_class}" /> 
    <property name="username" value="${My_JDTs_to_AgHost_Host_scheme.connection.username}" /> 
    <property name="password" value="${My_JDTs_to_AgHost_Host_scheme.connection.password}" /> 
    <property name="url" value="${My_JDTs_to_AgHost_Host_scheme.connection.url}" /> 
    <property name="maxIdle" value="${My_JDTs_to_AgHost_Host_scheme.minPoolSize}" /> 
    <property name="maxActive" value="${My_JDTs_to_AgHost_Host_scheme.maxPoolSize}" /> 
</bean> 

<!-- ******************************************************************** --> 
<!-- Setup each persistence unit --> 
<!-- ******************************************************************** --> 
      <!-- Configure a JPA vendor adapter --> 
      <bean id="My_JDTs_to_AgHost_Host_schemeJPAVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
       <property name="showSql" value="${My_JDTs_to_AgHost_Host_scheme.show_sql}" /> 
       <property name="generateDdl" value="${My_JDTs_to_AgHost_Host_scheme.generateDdl}" /> 
       <property name="databasePlatform" value="${My_JDTs_to_AgHost_Host_scheme.dialect}" /> 
      </bean> 
      <!-- EntityManager Factory that brings together the persistence unit, datasource, and JPA Vendor --> 
      <bean id="My_JDTs_to_AgHost_Host_scheme" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
       <property name="dataSource" ref="hostDataSource" /> 
       <property name="persistenceUnitName" value="My_JDTs_to_AgHost_Host_scheme" /> 
       <property name="jpaVendorAdapter" ref="My_JDTs_to_AgHost_Host_schemeJPAVendorAdapter" /> 
        <property name="jpaPropertyMap"> 
         <map> 
            <entry key="hibernate.transaction.manager_lookup_class" value="com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup" /> 
            <!-- <entry key="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory" /> --> 
            <entry key="hibernate.connection.release_mode" value="on_close" /> 
         </map> 
        </property> 
      </bean> 

这并不让我来更新我的数据,但不会回滚我的交易。所以,我正在使用一个事务管理器,org.springframework.jdbc.datasource.DataSourceTransactionManager。我更换了三种豆中的“设置事务管理器”块有:

<bean id="transactionManager" 
     class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
     <property name="dataSource" ref="hostDataSource" /> 
    </bean> 

这给我留下了测试与IllegalStateException异常失败:这种方法需要调用线程事务和不存在。异常还指出:

Possible causes: either you didn't start a transaction, 
it rolledback due to timeout, or it was committed already. 
ACTIONS: You can try one of the following: 
1. Make sure you started a transaction for the thread. 
2. Make sure you didn't terminate it yet. 
3. Increase the transaction timeout to avoid automatic rollback of long transactions; 
    check [http://www.atomikos.com/Documentation/JtaProperties][1] for how to do this. 

我承认不具有读取该文件尚未发布以及这些更新后,将这样做。我也发现这个线程,看起来很有希望:persistence-unit, different hibernate.transaction.manager_lookup_class property。您可以在Bean My_JDTs_to_AgHost_Host_scheme中看到注释。这失败相当悲惨。但是,也许我没有正确使用它。

我还发现此线程:Spring/JTA/JPA DAO integration test doesn't rollback?。这看起来很有希望,但我不知道如何使用它告诉我的。

+1

您是否尝试过在每个测试方法上使用@ Transactional而不是整个类?你是否期望数据在测试用例之间维护,但在完成课程后会回滚?或者你期望在每种​​方法之后回滚? –

+1

@JesseWebb在测试类级别放置'@Trasactional'注释是每次测试后回滚事务的标准做法 –

+0

@JesseWebb - 我希望测试在每次测试后回滚。我有和JohnB –

回答

1

答案tunred出在这里找到:Spring/JTA/JPA DAO integration test doesn't rollback?。我将数据源更改为以下内容。

<bean name="hostDataSource" class="com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean" destroy-method="close" > 
    <property name="driverClassName" value="${My_JDTs_to_AgHost_Host_scheme.connection.driver_class}" /> 
    <property name="user" value="${My_JDTs_to_AgHost_Host_scheme.connection.username}" /> 
    <property name="password" value="${My_JDTs_to_AgHost_Host_scheme.connection.password}" /> 
    <property name="url" value="${My_JDTs_to_AgHost_Host_scheme.connection.url}" /> 

    <property name="maxPoolSize" value="20" /> 
    <property name="reapTimeout" value="300" /> 
    <property name="uniqueResourceName" value="myappDatabase" /> 
</bean> 
0

您的加载环境中是否有DataSourceTransactionManager bean?

DataSourceTransactionManager example

见第9.3节

+0

它似乎没有。我会谷歌如何做到这一点。如果你有参考资料,我将不胜感激。 :-) –

+0

@ user471133更新了链接 –