Sha*_*Muh 1 session spring multithreading caching hibernate
我正在尝试对我的代码进行一些优化,并希望在我执行耗时操作的地方生成一个线程。在实施该优化的过程中,我遇到了一个让我发疯的问题。我简化了问题并为该特定问题创建了一个测试用例:(我使用的是 SpringJUnit4ClassRunner,因此事务在 testCRUD 方法的开头正确启动)
有人能帮我理解为什么 foundParent 在线程中为空吗?
private Semaphore sema = new Semaphore(0, false);
private long parentId;
@Test
public void testCRUD() {
//create
DBParent parent = null;
{
parent = new DBParent();
parentDao.persist(parent);
parentId = parent.getId();
assertTrue(parentId > 0);
parentDao.flush();
}
(new Thread(
new Runnable() {
public void run()
{
System.out.println("Start adding childs !");
DBParent foundParent = parentDao.findById(parentId);
assertTrue(foundParent != null); //ASSERTION FAILS HERE !!!!
System.out.println("Releasing semaphore !");
sema.release();
System.out.println("End adding childs !");
}
})).start();
try {
System.out.println("Acquiring semaphore !");
sema.acquire();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
==============================编辑==================== ============== 根据一个评论建议,我创建了一个产生线程的 threadManager bean。这是线程管理器的代码:
public class ThreadManager {
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void executeTask(String Name, Runnable task) {
(new Thread(task, Name)).start();
}
}
Run Code Online (Sandbox Code Playgroud)
然后在之前的测试中,我没有手动盯着线程,而是像这样在线程管理器中发布它:
@Autowired private ParentDao parentDao;
@Autowired private ThreadManager threadManager;
private Semaphore sema = new Semaphore(0, false);
private long parentId;
@Test
public void testCRUD() {
//create
DBParent parent = null;
{
parent = new DBParent();
parentDao.persist(parent);
parentId = parent.getId();
assertTrue(parentId > 0);
parentDao.flush();
}
threadManager.executeTask("BG processing...",
new Runnable() {
public void run()
{
System.out.println("Start adding childs !");
DBParent foundParent = parentDao.findById(parentId);
assertTrue(foundParent != null); //ASSERTION FAILS HERE !!!!
System.out.println("Releasing semaphore !");
sema.release();
System.out.println("End adding childs !");
}
});
try {
System.out.println("Acquiring semaphore !");
sema.acquire();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这也不起作用!!!:-(
事务上下文绑定到线程。因此,衍生线程中的代码与初始线程中的代码不在同一事务上下文中运行。因此,由于事务隔离(ACID 中的 I),生成的线程看不到初始线程的事务在数据库中插入了什么。
| 归档时间: |
|
| 查看次数: |
740 次 |
| 最近记录: |