@Transactional on run()无效

时间:2014-06-16 17:00:47

标签: multithreading hibernate spring-transactions

我正在使用:

org.springframework.orm.hibernate4.HibernateTransactionManager其API读取:

  

将Hibernate Session从指定的工厂绑定到线程,   可能允许每个工厂使用一个线程绑定的会话。

以下是我的问题代码:

@Transactional
    public void insertPerson(Person transientPerson) {
        System.out.println("Current session in insert "+sessionFactory.getCurrentSession()); // Line 1
        personDao.save(transientPerson);
        executeConcurrently();
    }  

    private void executeConcurrently() {
        new Thread(new Runnable() {
            @Transactional
            public void run() {
                System.out.println("This is a branew thread "+Thread.currentThread().getName());
                System.out.println("In the new thread, session = "+sessionFactory.getCurrentSession()); // Line 2
            }
        }).start();
    }

在第1行,我得到了明显的会话。但是第2行的执行显示了这个错误:
这是一个新的线程Thread-2

Exception in thread "Thread-2" org.hibernate.HibernateException: No Session found for current thread
    at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
    at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:978)
    at edu.sprhib.service.impl.PersonServiceImpl$1.run(PersonServiceImpl.java:55)
    at java.lang.Thread.run(Thread.java:724)

我不明白为什么会失败?根据我的理解,Spring应该创建一个全新的会话并将其与Thread-2的ThreadLocal相关联。我的理解错了还是代码?我同时尝试调试Spring代码和我的netbeans,即使将源代码连接到spring-orm jar后也无法调试它内部(请注意我不太擅长调试框架内部的代码)。

任何帮助将不胜感激。

提前致谢, 穆斯塔法

1 个答案:

答案 0 :(得分:1)

试试这个

@Transactional( propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void insertPerson(Person transientPerson) {
        System.out.println("Current session in insert "+sessionFactory.getCurrentSession()); // Line 1
        personDao.save(transientPerson);
        executeConcurrently();
    }  

    private void executeConcurrently() {
        new Thread(new Runnable() {
            @Transactional
            public void run() {
                System.out.println("This is a branew thread "+Thread.currentThread().getName());
                System.out.println("In the new thread, session = "+sessionFactory.getCurrentSession()); // Line 2
            }
        }).start();
    }

通过使用Propagation.REQUIRED Spring Container句柄会话,您不必担心Session对象

如果你的会话对象被销毁,容器会创建一个新的会话,如果我们将我们的交易称为propagation = Propagation.REQUIRED

,则提供会话