如何将 Hibernate 会话绑定到 Grails 中的线程?

问题描述 投票:0回答:4

我正在用 Grails 编写一个多线程应用程序,附加线程需要访问 GORM/Hibernate。当他们尝试访问 GORM 时,我收到错误“org.hibernate.HibernateException:没有 Hibernate 会话绑定到线程,并且配置不允许在此处创建非事务会话”。

好吧,公平地说,有人可以指导我设置线程以进行访问的最佳方法吗?错误消息听起来几乎像是您只需要更改一些配置选项,但我感觉,事情并不那么简单......

grails grails-orm hibernate-session
4个回答

14
投票

您需要将任何 GORM 调用放入 withTransaction 闭包中。摘自多线程讨论的示例 https://fbflex.wordpress.com/2010/06/11/writing-batch-import-scripts-with-grails-gsql-and-gpars/

单线程

user = User.findByUsername( photo.username )

多线程

User.withTransaction{
user = User.findByUsername( photo.username )
}

3
投票

withNewSession 也可以工作。 就我而言,我的更新优先级较低,最后一个更新始终可以“获胜”。

version: false
在这里也很重要,以避免 StaleObjectException:

     Thread.start {
        try {
            Widget.withNewSession {
                xxx()
                log.info "Asynchronously did some updates."
            }
        } catch (Exception ex) {
            log.error "Failed to asynchronously do something...", ex
        }
    }

1
投票

卢克戴利给出了正确的答案。不幸的是,链接已更改。因此,我将更新他的答案并提供一个代码示例以使这个答案独立。

Grails 应用程序中有一个名为

persistenceInterceptor
的 bean,可用于初始化 Hibernate 的持久性上下文/会话。您可以将 bean 注入控制器/服务类之一并启动一个新线程,例如使用以下代码片段。

class YourControllerOrService {
    PersistenceContextInterceptor persistenceInterceptor
    
    def someOperation() {
        ...
        Runnable yourTask = { ->
            try {
                if (persistenceInterceptor) {
                    persistenceInterceptor.init()
                }
            
                // execute the hibernate operations here in a transaction,
                // e.g. call a method annotated with @Transactional
                ...
            } catch (Exception e) {
                    log.error('Your error message', e)
            } finally {
                if (persistenceInterceptor) {
                    persistenceInterceptor.flush()
                    persistenceInterceptor.destroy()
                }
            }
        }
        Thread workerThread = new Thread(yourTask)
        workerThread.start()
        ...
    }
}

您将在 GitHub 上的 Grails JMS 插件中找到示例性实现。

PersistenceContextInterceptor 接口也可以在 GitHub 上找到。

© www.soinside.com 2019 - 2024. All rights reserved.