我正在尝试使用AbstractTransactionalJUnit4SpringContextTests的子类为部署在Weblogic 8.1上的遗留应用程序创建集成测试。
我的测试方法有以下注释:
@Test
@Rollback(true)
public void testDeployedEJBCall throws Exception {...}
我的测试类还引用了类型为org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean的bean,它代理了我的weblogic服务器上部署的EJB。
当我在测试方法中以顺序方式调用此代理bean上的方法时,事务会在测试结束时正确回滚。
e.g。 :
@Test
@Rollback(true)
public void testDeployedEJBCall throws Exception {
Long result1 = myejb.method(100L);
Long result2 = myejb.method(200L);
...
}
但是,我想对同一个EJB方法进行2次并行调用。因此我创建了一个实现Callable的内部类,以便在2个不同的Threads中调用我的方法,并希望并行运行它们。
但是,这样做似乎使ejb方法在我的事务之外被调用,并且没有任何回滚。
以下是我并行运行方法调用时完整测试类的内容:
import org.springframework.test.annotation.*;
@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
@ContextConfiguration(locations = {"classpath:path/to/tests-config.xml"})
@TransactionConfiguration(defaultRollback=true)
public final class IntegrationTests extends AbstractTransactionalJUnit4SpringContextTests {
@Autowired
protected JndiTemplate jndiTemplate;
@Resource
protected Proxy myEJB;
public IntegrationTests() {
super();
this.logger = Logger.getLogger(IntegrationTests.class);
}
@Test
@Rollback(true)
public void testDeployedEJBCall() throws Exception {
// Create a thread pool for parallel execution.
ExecutorService exec = Executors.newFixedThreadPool(2);
// Prepare the tasks for parallel execution
List<CallEJBTask> tasks = new ArrayList<CallEJBTask>();
tasks.add(new CallEJBTask(100L, this.myEJB));
tasks.add(new CallEJBTask(200L, this.myEJB));
// Execute all pending tasks in the exec Threadpool
List<Future<Long>> results = exec.invokeAll(tasks);
// Get the results of each task
Long result1 = results.get(0).get();
Long result2 = results.get(1).get();
...
}
}
private class CallEBJTask implements Callable<Long> {
private final Long valueToTest;
private final MyEJB myEJB;
public CallEJBTask(Long valueToTest, Proxy myEJBProxy)
this.valueToTest = valueToTest;
this.myEJB = (MyEJB)myEJBProxy;
}
public Long call() throws Exception {
return getResult();
}
public Long getResult() {
Long result = null;
try {
result = this.myEJB.method(this.patient);
} catch (Exception e) {
...
}
return result;
}
}
有没有办法让这次回滚?
感谢您的帮助。
此致
菲利普
答案 0 :(得分:2)
不是自动,不是。问题是两个额外的线程不参与事务,因此它们的操作不会回滚。
两个并行执行的目的是什么?如果这是你的目标,那么你不太可能用这种方法测试并发性问题。
编辑:问题在于测试并发性问题非常困难,因为您的测试充其量也是概率性的 - 成功或失败取决于可能仅在第十亿次运行中出现的微妙时序问题。有关基础知识的详细摘要,请参阅this Serverside article。
经验法则应该是尽可能避免手工编码线程,因为很难正确和难以测试。如果可以,请避免线程之间的共享状态,如果无法绕过它,请依赖java.util.concurrent
包中的并发数据结构和异步执行程序。