Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SpringJDBC测试中的事务回滚_Spring_Testing_Jdbc_Transactions_Rollback - Fatal编程技术网

SpringJDBC测试中的事务回滚

SpringJDBC测试中的事务回滚,spring,testing,jdbc,transactions,rollback,Spring,Testing,Jdbc,Transactions,Rollback,我试图在使用Spring测试时回滚JDBC事务,但没有成功。当我运行以下命令时,SQL更新总是提交的 package my.dao.impl; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.Rollback; impor

我试图在使用Spring测试时回滚JDBC事务,但没有成功。当我运行以下命令时,SQL更新总是提交的

package my.dao.impl;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.transaction.TransactionConfiguration;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.Statement;

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
@ContextConfiguration(locations={"classpath:ApplicationContext-test-DAOs.xml"})
@TransactionConfiguration(defaultRollback = true)
public class ConfirmationMatchingDAOImplTest {

    @Autowired
    private DataSource dataSource;

    @Test
    public void shouldInsertSomething() throws Exception {
        final Connection connection = dataSource.getConnection();
        final Statement statement = connection.createStatement();
        statement.executeUpdate("insert into TEST_INSERT values (1, 'hello')");
        statement.close();
        connection.close();
    }
}


我做错了什么


此外,我是否使用了过多的注释?我可以让它更干净一点吗?

这可能是因为您没有测试方法的
@Transactional
吗?

如果您没有使用
@TestExecutionListeners
注释显式配置测试执行侦听器,Spring默认配置
DependencyInjectionTestExecutionListener
DirtiesContextTestExecutionListener
TransactionalTestExecutionListener
TransactionalTestExecutionListener
提供具有默认回滚语义的事务测试执行。通过在测试类上显式声明
@TestExecutionListeners
,并从侦听器列表中省略
TransactionalTestExecutionListener
,可以禁用事务支持

还必须在类或方法级别添加
@Transactional
注释


您还必须使用来获取由DataSourceTransactionManager管理的事务连接。

在Spring中使用@transactional注释时,必须将以下行添加到Spring配置文件中:

<tx:annotation-driven transaction-manager="transactionManager"/>

事务管理器属性保存对Spring配置文件中定义的事务管理器bean的引用。这段代码告诉Spring在应用事务拦截器时使用@Transaction注释。没有它,@Transactional注释将被忽略,导致代码中没有使用任何事务


其他信息:

这条线

<tx:annotation-driven transaction-manager="transactionManager"/>

您需要在类级别添加
@Transactional
。 大概是这样的:

@TransactionConfiguration(transactionManager = "txManager",defaultRollback = true)
@Transactional
这里,
txManager
是来自
应用程序上下文
的事务管理器的实例或bean id

<!-- Transaction Manager -->
    <bean id="txManager"
          class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <tx:annotation-driven transaction-manager="txManager" />

如果您使用的是非xml方法,那么从3.1版开始,它就可以很好地工作

@Transactional
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestDbConfig.class, SomeService.class})
public class SomeTest {

@Inject
private SomeService someService;

@PersistenceContext
private EntityManager em;

@Test
public void someTest() {}
然后,测试配置采用这种形式。请注意@EnableTransactionManagement和您可以声明全局测试defaultRollback的事实。这对于大型项目尤其有用

@Configuration
@PropertySource(value = "classpath:app.properties")
@EnableTransactionManagement
@TransactionConfiguration(defaultRollback = true)
public class TestDbConfig {

//read the parameters from properties
@Value("${hibernate.dialect:unset}")
private String hibernateDialect;

@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
    return new PropertySourcesPlaceholderConfigurer();
}

@Bean
public PlatformTransactionManager transactionManager() {
    //for example
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());
    return transactionManager;
}

@Bean
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
    //set the datasource
    //set the JpaVendorAdapter
    //set the packagesToScan
    return some sort of LocalContainerEntityManagerFactoryBean;
}

@Bean
DataSource dataSource() {
    return dataSource from jndi or a DriverManagerDataSource();
}

}

添加此注释,测试用例中将不会回滚:

 @TransactionConfiguration(defaultRollback=false)
我的注释如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/../applicationContext.xml" })
@TransactionConfiguration(defaultRollback=true)
public class DBCreatorTest {

在尝试了上述许多组合之后,下面的设置对我有效,在测试成功后完全回滚

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:datasource-context-test.xml"})
@TransactionConfiguration(defaultRollback = true)
@Transactional
public class DataAccessTest 
{


    @Test
    public void testSaveRecords()
    { ... }
}

我添加了@Transactional,但没有效果。我还添加了@Rollback,但仍然没有效果。我删除了@TestExecutionListeners并添加了@Transactional。然后,我不得不将transactionManager bean添加到应用程序上下文(DataSourceTransactionManager)。Txn没有回滚,所以我添加了@TransactionConfiguration(defaultRollback=true)。Txn仍然没有回滚,所以我在测试方法中添加了@Rollback。直到那时,我才看到Spring日志,它正在回滚txn,但更新仍然被持久化到DB。可能与SQL Server及其驱动程序有关?在我的回答中添加了DataSourceUtils。啊,我没有收到你上次评论的通知。同时,我更改了上下文,将数据源包装在TransactionWaredataSourceProxy中。成功了。好了,两种方法做同样的事情。现在看看这7个注释中哪一个我可以去掉,并且仍然可以使用。我不记得问题到底是什么,但是谢谢你提供的额外信息。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/../applicationContext.xml" })
@TransactionConfiguration(defaultRollback=true)
public class DBCreatorTest {
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:datasource-context-test.xml"})
@TransactionConfiguration(defaultRollback = true)
@Transactional
public class DataAccessTest 
{


    @Test
    public void testSaveRecords()
    { ... }
}