Spring JDBC 测试中的事务回滚
我试图在使用 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();
}
}
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
<property name="url" value="jdbc:sqlserver://makeitfunky:1490;databaseName=fonzie"/>
<property name="username" value="ralph"/>
<property name="password" value="p0n1es_R_kew1"/>
</bean>
我做错了什么?
另外,我是否使用了太多注释?我可以让它干净一点吗?
I'm trying to get JDBC transaction rollback when using Spring-test without success. When I run the following the SQL update is always committed.
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();
}
}
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
<property name="url" value="jdbc:sqlserver://makeitfunky:1490;databaseName=fonzie"/>
<property name="username" value="ralph"/>
<property name="password" value="p0n1es_R_kew1"/>
</bean>
What am I doing wrong?
Additionally, am I using too many annotations? Can I make it a bit cleaner?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
如果您没有使用 @TestExecutionListeners 注解显式配置测试执行监听器,Spring 默认配置 DependencyInjectionTestExecutionListener、DirtiesContextTestExecutionListener 和 TransactionalTestExecutionListener /代码>。
TransactionalTestExecutionListener
提供具有默认回滚语义的事务测试执行。通过在测试类上显式声明@TestExecutionListeners
并从侦听器列表中省略TransactionalTestExecutionListener
,您将禁用事务支持。您还必须在类或方法级别添加
@Transactional
注释。您还必须使用 DataSourceUtils 获取由 DataSourceTransactionManager 管理的事务连接。
If you do not explicitly configure test execution listeners using the
@TestExecutionListeners
annotation, Spring configures by defaultDependencyInjectionTestExecutionListener
,DirtiesContextTestExecutionListener
, andTransactionalTestExecutionListener
.TransactionalTestExecutionListener
provides transactional test execution with default rollback semantics. By explicitly declaring@TestExecutionListeners
on your test class and omittingTransactionalTestExecutionListener
from the listeners list, you are disabling transactional support.You must also add the
@Transactional
annotation at the class or method level.You must also use DataSourceUtils to get a transactional Connection managed by DataSourceTransactionManager.
如果您使用非 xml 方法,那么从版本 3.1 开始,这可以很好地工作,
测试配置将采用这种形式。注意 @EnableTransactionManagement 以及您可以声明全局测试 defaultRollback 的事实。这对于大型项目特别有用。
}
If you are using the non-xml method this works nicely since about version 3.1
The test config then takes this form. Notice @EnableTransactionManagement and the fact you can declare a global test defaultRollback. This becomes particularly useful on a large projects.
}
添加此注释,测试用例中不会回滚:
我的注释如下所示:
add this annotation, and no roll back will be in test cases:
My annotation looks like this:
是否是因为您没有用于测试方法的
@Transactional
?Could it be because you do not have an
@Transactional
for the test method?在 Spring 中使用 @Transactional 注释时,必须将以下行添加到 Spring 配置文件中:
transaction-manager 属性保存对 Spring 配置文件中定义的事务管理器 bean 的引用。这段代码告诉Spring在应用事务拦截器时使用@Transaction注解。如果没有它,@Transactional 注释将被忽略,导致代码中不会使用任何事务。
IBM 网站上的来源
When using the @Transactional annotation in Spring, you must add the following line to your Spring configuration file:
The transaction-manager property holds a reference to the transaction manager bean defined in the Spring configuration file. This code tells Spring to use the @Transaction annotation when applying the transaction interceptor. Without it, the @Transactional annotation is ignored, resulting in no transaction being used in your code.
Source on IBM website
附加信息:
对于此行,
transaction-manager
属性的默认值为“transactionManager”。仅当 transactionManager 的 bean id/名称不是“transactionManager”时,才需要此属性。
所以你只需要设置:
additional informations :
for this line
The default value of the
transaction-manager
attribute is "transactionManager".This attribute is required only if the bean id/name of the transactionManager is not 'transactionManager'.
So you just have to set :
您需要在类级别添加
@Transactional
。类似这样的:
这里
txManager
是来自应用程序上下文
的事务管理器的实例或bean id。You need to add
@Transactional
at class level.Something like this :
Here
txManager
is an instance or bean id of Transaction manager fromapplication context
.在尝试了上面的很多组合之后,以下设置对我有用,在测试成功后完全回滚。
After trying out a lot of the above combinations, the following setup worked for me with full rollback after the test is successful.