Spring事务测试。嵌套事务不会回滚

时间:2014-11-30 23:28:16

标签: java spring oracle transactions

我尝试使用DbUnit + Spring(4.1.1)测试+ MyBatis + Oracle

来实现集成测试

我正在做以下事情:

  1. 考试前:(a)公开交易; (b)插入只读的共同父数据集(适用于所有测试方法)
  2. 将测试类标记为Transactional(propogation = NESTED)。因此,每个测试方法都应该在自己的事务中执行,然后回滚它。嵌套 - 因为我希望能够访问"在测试类之前插入的数据"父事务中的方法(因此propogation = REQUIRED_NEW不是一个选项)
  3. 在测试类回滚父事务之后。
  4. 问题是嵌套事务没有回滚。如果方法A插入数据,则方法B会看到该数据。

    可能是JDBC(11.2.0.1.0)驱动程序问题(因为spring使用Savepoint方法)还是Oracle(11g)?

    我已附加简化(一体化)测试以证明此问题:

        @RunWith(SpringJUnit4ClassRunner.class)
        @ContextConfiguration({ "/core-dao-config.xml", "/test-context.xml" })
        @TestExecutionListeners({DependencyInjectionTestExecutionListener.class,
                TransactionTest.class, TransactionalTestExecutionListener.class})
        @Transactional(propagation = Propagation.NESTED)
    
        public class TransactionTest extends AbstractTestExecutionListener
        {
    
        public TransactionTest(){}
    
        DataSource dataSource;
    
        DataSourceTransactionManager txManager;
    
        protected void injectDependencies(final TestContext testContext) throws Exception {
    
            dataSource = testContext.getApplicationContext().getBean(DataSource.class);
            txManager = testContext.getApplicationContext().getBean(DataSourceTransactionManager.class);
    
        }
    
        @Override
        public void beforeTestClass(TestContext testContext) throws Exception {
            injectDependencies(testContext);
            final TransactionStatus transaction = txManager.getTransaction(new DefaultTransactionAttribute());
            testContext.setAttribute("parenttx", transaction);
        }    
    
        @Autowired
        SomeDao someDao;
    
        @Test
        public void testTx() {
            final DbObject domainObject = new DbObject();
            domainObject.setKey(-303L);
            someDao.add(domainObject);
    
            assertNotNull(someDao.findByKey(-303L));
        }
    
        @Test
        public void testInserted() {
            assertNull(someDao.findByKey(-303L));
        }
    
        @Override
        public void afterTestClass(TestContext testContext) throws Exception {
            final TransactionStatus parenttx =(TransactionStatus)testContext.getAttribute("parenttx");
            Validate.notNull(parenttx);
            txManager.rollback(parenttx);
        }
    }
    

    因此,当方法testTx插入记录时,testInserted会看到它并且失败。但是日志说数据已经回滚:

    00:39:09.892 [main] INFO  o.s.t.c.t.TransactionContext - Began transaction (1) for test context [DefaultTestContext@74fbc266 testClass = TransactionTest, testInstance = TransactionTest@3c97f28a, testMethod = testTx@TransactionTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@1bb4611a testClass = TransactionTest, locations = '{classpath:/core-dao-config.xml, classpath:/test-context.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]; transaction manager [org.springframework.jdbc.datasource.DataSourceTransactionManager@5f53002b]; rollback [true]
    00:39:09.896 [main] DEBUG SomeDao - Running add using Connection [oracle.jdbc.driver.LogicalConnection@34311f74]
    00:39:10.456 [main] DEBUG SomeDao - Running findOne
    00:39:10.458 [main] DEBUG SomeDao - Running find: gkey=(-303) using Connection [oracle.jdbc.driver.LogicalConnection@34311f74]
    00:39:10.752 [main] DEBUG SomeDao - <==      Total: 1
    00:39:10.968 [main] INFO  o.s.t.c.t.TransactionContext - Rolled back transaction for test context [DefaultTestContext@74fbc266 testClass = TransactionTest, testInstance = TransactionTest@3c97f28a, testMethod = testTx@TransactionTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@1bb4611a testClass = TransactionTest, locations = '{classpath:/core-dao-config.xml, classpath:/test-context.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]].
    00:39:11.184 [main] INFO  o.s.t.c.t.TransactionContext - Began transaction (1) for test context [DefaultTestContext@74fbc266 testClass = TransactionTest, testInstance = TransactionTest@3bd8bd66, testMethod = testInserted@TransactionTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@1bb4611a testClass = TransactionTest, locations = '{classpath:/core-dao-config.xml, classpath:/test-context.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]; transaction manager [org.springframework.jdbc.datasource.DataSourceTransactionManager@5f53002b]; rollback [true]
    00:39:11.187 [main] DEBUG SomeDao - Running findOne
    00:39:11.187 [main] DEBUG SomeDao - Running find: gkey=(-303)
    00:39:11.402 [main] INFO  o.s.t.c.t.TransactionContext - Rolled back transaction for test context [DefaultTestContext@74fbc266 testClass = TransactionTest, testInstance = TransactionTest@3bd8bd66, testMethod = testInserted@TransactionTest, testException = java.lang.AssertionError: expected null, but was:<DbObject{row=BaseRow{rownumStr=row#(1), status=UNCHANGED, rowscn=D, rowid=AAAkSFAAcAAAQ2uAAX, creator=TEST, created=Sun Nov 30 14:38:19 EET 2014}, gkey=-303}>, mergedContextConfiguration = [MergedContextConfiguration@1bb4611a testClass = TransactionTest, locations = '{classpath:/core-dao-config.xml, classpath:/test-context.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]].
    

    有什么想法吗?

0 个答案:

没有答案