Java 弹簧试验';s@Rollback不';不要回滚任何东西
工作代码如下:Java 弹簧试验';s@Rollback不';不要回滚任何东西,java,transactions,spring-test,Java,Transactions,Spring Test,工作代码如下: //import everything @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = Test2.TestConfiguration.class) @Transactional public class Test2 { @Autowired private DataSource datasource; @BeforeTransaction pub
//import everything
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Test2.TestConfiguration.class)
@Transactional
public class Test2 {
@Autowired
private DataSource datasource;
@BeforeTransaction
public void createDatabase() throws SQLException {
DataSourceUtils .getConnection(datasource)
.createStatement()
.execute("CREATE TABLE USERS (id bigint, size bigint, primary key (id))");
}
@Rollback
@Test
public void test() throws SQLException {
DataSourceUtils .getConnection(datasource)
.createStatement()
.execute("INSERT INTO USERS VALUES (5, 5)");
}
@AfterTransaction
public void dropTable() throws SQLException {
ResultSet rs = DataSourceUtils .getConnection(datasource)
.createStatement()
.executeQuery("SELECT * FROM USERS");
boolean isEmpty = !rs.next();
if (isEmpty) {
System.out.println("Rollback succeeded");
} else {
System.out.println("Rollback failed");
}
rs.close();
datasource .getConnection()
.createStatement()
.execute("DROP TABLE USERS");
}
@Configuration
public static class TestConfiguration {
@Bean
public DataSource driverManagerDataSource() {
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
String dbURI = "database/tests/DerbyDB/db";
String connectionString = "jdbc:derby:" + dbURI;
if (!new File(dbURI).exists()) connectionString += ";create=true";
driverManagerDataSource.setUrl(connectionString);
driverManagerDataSource.setDriverClassName("org.apache.derby.jdbc.EmbeddedDriver");
return driverManagerDataSource;
}
@Bean
public PlatformTransactionManager platformTransactionManager() {
PlatformTransactionManager ptm = new DataSourceTransactionManager(driverManagerDataSource());
return ptm;
}
}
}
已解决问题:
我想在每次测试后使用@rollback注释回滚数据库状态。不幸的是,它不起作用
这是我的测试课:
//import everything
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Test2.TestConfiguration.class)
@Transactional
public class Test2 {
@Autowired
private DataSource datasource;
@BeforeTransaction
public void createTable() throws SQLException {
datasource .getConnection()
.createStatement()
.execute("CREATE TABLE USERS (id bigint, size bigint, primary key (id))");
}
@Rollback
@Test
public void test() throws SQLException {
datasource .getConnection()
.createStatement()
.execute("INSERT INTO USERS VALUES (5, 5)");
}
@AfterTransaction
public void dropTable() throws SQLException {
ResultSet rs = datasource .getConnection()
.createStatement()
.executeQuery("SELECT * FROM USERS");
boolean isEmpty = !rs.next();
if (isEmpty) {
System.out.println("Rollback succeeded");
} else {
System.out.println("Rollback failed");
}
rs.close();
datasource .getConnection()
.createStatement()
.execute("DROP TABLE USERS");
}
@Configuration
public static class TestConfiguration {
@Bean
public DataSource driverManagerDataSource() {
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
String dbURI = "database/tests/DerbyDB/db";
String connectionString = "jdbc:derby:" + dbURI;
if (!new File(dbURI).exists()) connectionString += ";create=true";
driverManagerDataSource.setUrl(connectionString);
driverManagerDataSource.setDriverClassName("org.apache.derby.jdbc.EmbeddedDriver");
return driverManagerDataSource;
}
@Bean
public PlatformTransactionManager platformTransactionManager() {
PlatformTransactionManager ptm = new DataSourceTransactionManager(driverManagerDataSource());
return ptm;
}
}
}
Spring声称它回滚了数据库,但事实并非如此,因为记录仍然存在。我如何让它工作
gru 01, 2016 12:26:14 PM org.springframework.test.context.transaction.TransactionContext startTransaction
INFO: Began transaction (1) for test context [DefaultTestContext@457c9034 testClass = Test2, testInstance = tyvrel.tastas.persistence.Test2@345f69f3, testMethod = test@Test2, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@e15b7e8 testClass = Test2, locations = '{}', classes = '{class tyvrel.tastas.persistence.Test2$TestConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]; transaction manager [org.springframework.jdbc.datasource.DataSourceTransactionManager@3bf9ce3e]; rollback [true]
gru 01, 2016 12:26:14 PM org.springframework.test.context.transaction.TransactionContext endTransaction
INFO: Rolled back transaction for test context [DefaultTestContext@457c9034 testClass = Test2, testInstance = tyvrel.tastas.persistence.Test2@345f69f3, testMethod = test@Test2, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@e15b7e8 testClass = Test2, locations = '{}', classes = '{class tyvrel.tastas.persistence.Test2$TestConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]].
Rollback failed
gru 01, 2016 12:26:14 PM org.springframework.context.support.GenericApplicationContext doClose
INFO: Closing org.springframework.context.support.GenericApplicationContext@ae45eb6: startup date [Thu Dec 01 12:26:12 CET 2016]; root of context hierarchy
完整日志如下所示:
gru 01, 2016 12:26:12 PM org.springframework.test.context.support.DefaultTestContextBootstrapper getDefaultTestExecutionListenerClassNames
INFO: Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
gru 01, 2016 12:26:12 PM org.springframework.test.context.support.DefaultTestContextBootstrapper getTestExecutionListeners
INFO: Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@69d9c55, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@13a57a3b, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@7ca48474, org.springframework.test.context.support.DirtiesContextTestExecutionListener@337d0578, org.springframework.test.context.transaction.TransactionalTestExecutionListener@59e84876, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@61a485d2]
gru 01, 2016 12:26:12 PM org.springframework.context.support.GenericApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.GenericApplicationContext@ae45eb6: startup date [Thu Dec 01 12:26:12 CET 2016]; root of context hierarchy
gru 01, 2016 12:26:13 PM org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
INFO: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
gru 01, 2016 12:26:13 PM org.springframework.jdbc.datasource.DriverManagerDataSource setDriverClassName
INFO: Loaded JDBC driver: org.apache.derby.jdbc.EmbeddedDriver
gru 01, 2016 12:26:14 PM org.springframework.test.context.transaction.TransactionContext startTransaction
INFO: Began transaction (1) for test context [DefaultTestContext@457c9034 testClass = Test2, testInstance = tyvrel.tastas.persistence.Test2@345f69f3, testMethod = test@Test2, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@e15b7e8 testClass = Test2, locations = '{}', classes = '{class tyvrel.tastas.persistence.Test2$TestConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]; transaction manager [org.springframework.jdbc.datasource.DataSourceTransactionManager@3bf9ce3e]; rollback [true]
gru 01, 2016 12:26:14 PM org.springframework.test.context.transaction.TransactionContext endTransaction
INFO: Rolled back transaction for test context [DefaultTestContext@457c9034 testClass = Test2, testInstance = tyvrel.tastas.persistence.Test2@345f69f3, testMethod = test@Test2, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@e15b7e8 testClass = Test2, locations = '{}', classes = '{class tyvrel.tastas.persistence.Test2$TestConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]].
Rollback failed
gru 01, 2016 12:26:14 PM org.springframework.context.support.GenericApplicationContext doClose
INFO: Closing org.springframework.context.support.GenericApplicationContext@ae45eb6: startup date [Thu Dec 01 12:26:12 CET 2016]; root of context hierarchy
gru 01201612:26:12 PM org.springframework.test.context.support.DefaultTestContextBootstrapper getDefaultTestExecutionListenerClassNames
信息:从位置[META-INF/spring.factories]加载了默认的TestExecutionListener类名:[org.springframework.test.context.web.ServletTestExecutionListener,org.springframework.test.context.support.dirtiesContextBeforeMistestExecutionListener,org.springframework.test.context.support.DependencyInjectionTestExecutionListener,org.springframework.test.context.support.DirtiesContextTestExecutionListener,org.springframework.test.contextt、 transaction.TransactionalTestExecutionListener,org.springframework.test.context.jdbc.sqlscriptsteExecutionListener]
gru 01201612:26:12 PM org.springframework.test.context.support.DefaultTestContextBootstrapper getTestExecutionListeners
信息:使用TestExecutionListeners:[org.springframework.test.context.web。ServletTestExecutionListener@69d9c55,org.springframework.test.context.support。DirtiesContextBeforeModesTestExecutionListener@13a57a3b,org.springframework.test.context.support。DependencyInjectionTestExecutionListener@7ca48474,org.springframework.test.context.support。DirtiesContextTestExecutionListener@337d0578,org.springframework.test.context.transaction。TransactionalTestExecutionListener@59e84876,org.springframework.test.context.jdbc。SqlScriptsTestExecutionListener@61a485d2]
gru 01201612:26:12 PM org.springframework.context.support.GenericaApplicationContext prepareRefresh
信息:刷新org.springframework.context.support。GenericApplicationContext@ae45eb6:启动日期[Thu Dec 01 12:26:12 CET 2016];上下文层次结构的根
gru 01201612:26:13 PM org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
信息:找到并支持JSR-330“javax.inject.inject”注释进行自动连接
gru 01201612:26:13 PM org.springframework.jdbc.datasource.driverManager数据源setDriverClassName
信息:加载的JDBC驱动程序:org.apache.derby.JDBC.EmbeddedDriver
gru 01201612:26:14 PM org.springframework.test.context.transaction.TransactionContext startTransaction
信息:已开始测试上下文的事务(1)[DefaultTestContext@457c9034testClass=Test2,testInstance=tyvrel.tastas.persistence。Test2@345f69f3,testMethod=test@Test2,testException=[null],mergedContextConfiguration=[MergedContextConfiguration@e15b7e8testClass=Test2,位置=“{}”,类=”{class tyvrel.tastas.persistence.Test2$TestConfiguration}',ContextInitializerClass='[]',activeProfiles='{}',propertySourceLocations='{}',propertySourceProperties='{}',contextCustomizers=set[[empty]],contextLoader='org.springframework.test.context.support.DelegatingSmartContextLoader',parent=[null]];事务管理器[org.springframework.jdbc.datasource。DataSourceTransactionManager@3bf9ce3e];回滚[真]
gru 01201612:26:14 PM org.springframework.test.context.transaction.TransactionContext endTransaction
信息:测试上下文的回滚事务[DefaultTestContext@457c9034testClass=Test2,testInstance=tyvrel.tastas.persistence。Test2@345f69f3,testMethod=test@Test2,testException=[null],mergedContextConfiguration=[MergedContextConfiguration@e15b7e8testClass=Test2,位置=“{}”,类=”{class tyvrel.tastas.persistence.Test2$TestConfiguration}',ContextInitializerClass='[]',activeProfiles='{}',propertySourceLocations='{}',propertySourceProperties='{}',contextCustomizers=set[[empty]],contextLoader='org.springframework.test.context.support.DelegatingSmartContextLoader',parent=[null]]。
回滚失败
gru 01201612:26:14 PM org.springframework.context.support.GenericaApplicationContext doClose
信息:正在关闭org.springframework.context.support。GenericApplicationContext@ae45eb6:启动日期[Thu Dec 01 12:26:12 CET 2016];上下文层次结构的根
据我所知,您正在测试方法中手动创建一个新的、独立的Spring上下文,它在初始化过程中创建表
由于该上下文使用它自己的事务管理器和数据源,因此它不会受到@Rollback
注释的影响-该注释是在为整个测试类定义的(隐式)spring上下文的上下文中处理的
还要注意的是,在某些数据库中,您无法回滚
CREATE
命令(但不确定Derby)
更新 另一个问题是,当您通过
datasource.getConnection()
获取连接时,实际上没有使用事务管理器
从文件:
通过DataSourceUtils.getConnection(DataSource)
检索JDBC连接需要应用程序代码,而不是标准的Java EE样式DataSource.getConnection()
调用。Spring类,如JdbcTemplate
隐式使用此策略
我认为
printTableName()
方法中的这一行con.close();
导致了这个问题
事务在关闭连接时提交
最好使用entitymanager或来处理事务。不幸的是,删除
con.close();
并不能解决问题。@Tyvrel是否尝试显式回滚?con.rollback()
当然。它也不起作用。而且没有抓住要点-我需要了解@Rollback
是如何工作的,我想不出比执行简单的sql脚本更简单的练习。con.close()
关闭一个通过编程创建的非mana连接