下面是simple @DataJPATest的一部分。两个测试是相同的。
当它在单个线程中执行时,回滚没有问题。
@Test
void SingleThreadTest1() throws RequesterException, InterruptedException {
System.out.println("(before)count: " + logRepository.count());
App app = appRepository.findByName("TestApp").orElseThrow();
myService.loggingTransaction(app);
System.out.println("(after)count: " + logRepository.count());
}
@Test
void SingleThreadTest2() throws RequesterException, InterruptedException {
System.out.println("(before)count: " + logRepository.count());
App app = appRepository.findByName("TestApp").orElseThrow();
myService.loggingTransaction(app);
System.out.println("(after)count: " + logRepository.count());
}
测试结果:
#SingleThreadTest1
(before)count: 0
(after)count: 1
#SingleThreadTest2
(before)count: 0
(after)count: 1
但在多线程中操作时不会回滚。
@DataJpaTest
class ServiceTest {
static final int CONCURRENCY = 1;
@Test
void MultiThreadTest1() throws RequesterException, InterruptedException {
System.out.println("(before)count: " + logRepository.count());
App app = appRepository.findByName("TestApp").orElseThrow();
// --------From Here: Spawn sub thread---------
ThreadPoolExecutor executor = new ThreadPoolExecutor(CONCURRENCY, CONCURRENCY, 1, TimeUnit.MINUTES, new SynchronousQueue<>());
executor.prestartAllCoreThreads();
List<Callable<OptoutMessage>> callables = IntStream.range(0, CONCURRENCY)
.<Callable<OptoutMessage>>mapToObj(i -> () -> myService.loggingTransaction(app))
.toList();
List<Future<OptoutMessage>> futures = executor.invokeAll(callables);
executor.shutdownNow();
// ------------------Ultil here----------------
System.out.println("(after)count: " + logRepository.count());
}
@Test
void MultiThreadTest2() throws RequesterException, InterruptedException {
System.out.println("(before)count: " + logRepository.count());
App app = appRepository.findByName("TestApp").orElseThrow();
// --------From Here: Spawn sub thread---------
ThreadPoolExecutor executor = new ThreadPoolExecutor(CONCURRENCY, CONCURRENCY, 1, TimeUnit.MINUTES, new SynchronousQueue<>());
executor.prestartAllCoreThreads();
List<Callable<OptoutMessage>> callables = IntStream.range(0, CONCURRENCY)
.<Callable<OptoutMessage>>mapToObj(i -> () -> myService.loggingTransaction(app))
.toList();
List<Future<OptoutMessage>> futures = executor.invokeAll(callables);
executor.shutdownNow();
// ------------------Ultil here----------------
System.out.println("(after)count: " + logRepository.count());
}
测试结果:
#MultiThreadTest1
(before)count: 0
(after)count: 1
#MultiThreadTest2
(before)count: 1 // <- IT SHOULD BE 0 !!!
(after)count: 2
问题:
1.为什么@DataJPATest
在子线程中发生事务时不回滚?
1.在这种情况下,我应该如何回滚@Test
之后的数据?
1条答案
按热度按时间kokeuurv1#
我们最近遇到了类似的问题。
问题1:我不能给予一个充分的答案,因为我也不知道它为什么不回滚。
问题2:对我们有效的是添加注解
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/test/annotation/DirtiesContext.html