Java Spring测试:执行测试方法后不回滚事务

Java Spring测试:执行测试方法后不回滚事务,java,multithreading,transactions,rollback,spring-test,Java,Multithreading,Transactions,Rollback,Spring Test,我正在尝试使用AbstractTransactionalJUnit4SpringContextTests的子类为部署在Weblogic 8.1上的遗留应用程序创建集成测试 我的测试方法有以下注释: @Test @Rollback(true) public void testDeployedEJBCall throws Exception {...} 我的测试类还引用类型为org.springframework.ejb.access.simpleRemoteStatesessionProxyFa

我正在尝试使用AbstractTransactionalJUnit4SpringContextTests的子类为部署在Weblogic 8.1上的遗留应用程序创建集成测试

我的测试方法有以下注释:

@Test
@Rollback(true)
public void testDeployedEJBCall throws Exception {...}
我的测试类还引用类型为org.springframework.ejb.access.simpleRemoteStatesessionProxyFactoryBean的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方法进行两次并行调用。因此,我创建了一个实现可调用的内部类,以便在两个不同的线程中调用我的方法,并希望并行运行这些方法。
然而,这样做似乎会使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;   
    } 
}
import org.springframework.test.annotation.*;
@RunWith(SpringJUnit4ClassRunner.class)
@交易的
@ContextConfiguration(位置={“classpath:path/to/tests config.xml”})
@TransactionConfiguration(defaultRollback=true)
公共最终类集成测试扩展了AbstractTransactionalJUnit4SpringContextTests{
@自动连线
受保护的JNDemplate JNDemplate;
@资源
受保护的代理服务器;
公共集成测试(){
超级();
this.logger=logger.getLogger(IntegrationTests.class);
}
@试验
@回滚(true)
public void testDeployedEJBCall()引发异常{
//为并行执行创建线程池。
ExecutorService exec=Executors.newFixedThreadPool(2);
//准备并行执行的任务
列表任务=新建ArrayList();
添加(新调用的jbtask(100L,this.myEJB));
添加(新调用的jbtask(200L,this.myEJB));
//在exec线程池中执行所有挂起的任务
列表结果=exec.invokeAll(任务);
//获取每个任务的结果
Long result1=results.get(0.get();
Long result2=results.get(1.get();
...
}
}
私有类CallEBJTask实现可调用{
私人最终长期价值评估师;
私人决赛;
public CallEJBTask(Long valueToTest,Proxy myEJBProxy)
this.valueToTest=valueToTest;
this.myEJB=(myEJB)myEJBProxy;
}
public Long call()引发异常{
返回getResult();
}
公共长getResult(){
长结果=空;
试一试{
结果=此.myEJB.方法(此患者);
}捕获(例外e){
...
}
返回结果;
} 
}
有没有办法让这个回滚

谢谢你的帮助

问候,


Philippe

不是自动的,不是。问题是两个额外的线程不参与事务,因此它们的操作不会回滚

两次并行执行的目的是什么?如果这正是您的目标,那么您不太可能用这种方法测试并发性问题

编辑:问题是并发性问题的测试非常困难,因为您的测试充其量是概率性的——成功或失败取决于细微的时间问题,这些问题可能只会在第十亿次运行时出现。有关基础知识的详细摘要,请参见


经验法则应该是尽可能避免手动编码线程,因为这很难正确进行,也很难进行测试。如果可以,请避免线程之间的共享状态,如果没有办法,请依赖
java.util.concurrent
包中的并发数据结构和异步执行器。

是的,这正是我的目标。。。我应该使用什么方法来代替?我考虑的另一种可能性是在我的测试方法的标题中使用@Repeat(someBigNumber)在两台不同的机器上运行相同的测试。。。那行吗?嗯。。。我看过那篇文章。。。这不正是我在示例中所做的吗?