Spring 中的线程

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)

不幸的是,这也不起作用!!!:-(

JB *_*zet 5

事务上下文绑定到线程。因此,衍生线程中的代码与初始线程中的代码不在同一事务上下文中运行。因此,由于事务隔离(ACID 中的 I),生成的线程看不到初始线程的事务在数据库中插入了什么。