Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/grails/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Grails 无法打开事务的休眠会话_Grails - Fatal编程技术网

Grails 无法打开事务的休眠会话

Grails 无法打开事务的休眠会话,grails,Grails,我正在开发一个grails应用程序(服务器),用于跟踪Wi-Fi网络中的移动设备。用户将向运行在grails applicion(服务器)上的Web服务发送请求,同时发送Mobileid和Wi-Fi IP地址 在我的grails应用程序中,我启动了多个外部java线程,每个线程将ping每个移动设备的Wi-Fi IP地址(每个设备跟踪一个线程)。如果无法访问任何设备IP,则我将从外部线程将数据库中的移动状态更新为“已断开”。这里只有我面临的问题,如果多个设备处于不可访问状态,那么多个线程将使用域

我正在开发一个grails应用程序(服务器),用于跟踪Wi-Fi网络中的移动设备。用户将向运行在grails applicion(服务器)上的Web服务发送请求,同时发送Mobileid和Wi-Fi IP地址

在我的grails应用程序中,我启动了多个外部java线程,每个线程将ping每个移动设备的Wi-Fi IP地址(每个设备跟踪一个线程)。如果无法访问任何设备IP,则我将从外部线程将数据库中的移动状态更新为“已断开”。这里只有我面临的问题,如果多个设备处于不可访问状态,那么多个线程将使用域更新同一表中每个设备的状态

org.springframework.transaction.CannotCreateTransactionException:无法为事务打开Hibernate会话;嵌套异常是java.lang.NullPointerException 位于org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:596) 位于org.codehaus.groovy.grails.orm.hibernate.GrailsHibernateTransactionManager.super$3$doBegin(GrailsHibernateTransactionManager.groovy) 位于sun.reflect.GeneratedMethodAccessor492.invoke(未知源) 在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)中 位于java.lang.reflect.Method.invoke(Method.java:597) 位于org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:88) 位于groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233) 位于groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1058) 位于groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1070) 位于org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodOnSuperN(ScriptBytecodeAdapter.java:127)

我的代码:

线程中的ping设备

try {
    final InetAddress inet = InetAddress.getByName(ipAddress);
    boolean status = inet.isReachable(5000);
    if (status) {
        pool.run(MobileDeviceTracker.deviceMap.get(mobileId));
    } else {
         // Calling service to update the status of device as disconnected
        getUserMobileService().deviceDisconnected(mobileId, ipAddress);
    }
} catch (Exception e) { }
更新数据库中的状态

class DisconnectionService implements UserMobileServiceInt{
     static transactional = true


    def void deviceDisconnected(String mobileId, String wifiIp){
        try{
            def mobile = Mobile.findByMobileId(mobileId)
            def userMobile = UserMobile.findByMobileAndWifiIp(mobile, wifiIp)
            userMobile.withTransaction {tx ->               
                userMobile.action = Constants.MOBILE_STATUS_DISCONNECTED
                userMobile.alarmStatus = Constants.ALARM_STATUS_TURNED_ON
                userMobile.modifiedDate = new Date()
                userMobile.save(flush: true)
        }
        }catch(Exception e){
            e.printStackTrace()
        }

我在最后4天尝试,但无法解决此问题。

将读取内容移动到事务中,否则它们将处于断开连接的会话中,而不是事务创建的会话中。另外,最好在类上调用静态方法,而不是在实例上(在Groovy和Java中):


将读取移动到事务中,否则它们将处于断开连接的会话中,而不是事务创建的会话中。另外,最好在类上调用静态方法,而不是在实例上(在Groovy和Java中):


我不需要传播错误的信息和糟糕的做事方式。伯特和格雷姆的答案都会奏效。我刚刚写了一篇文章。

我不需要传播错误的信息和糟糕的做事方式。伯特和格雷姆的答案都会奏效。我只是写了一个.

而不是使用Tiggerizzy建议的冗长绑定代码。最好在域类上使用内置的withNewSession方法:

Mobile.withNewSession {
   // your code here
}

而不是使用Tiggerizzy建议的详细绑定代码。最好在域类上使用内置的withNewSession方法:

Mobile.withNewSession {
   // your code here
}

当我使用Domain.withNewSession时,我遇到以下异常:org.springframework.dao.DataAccessResourceFailureException:无法打开Hibernate会话;嵌套异常为org.hibernate.SessionException:会话已关闭!位于org.springframework.orm.hibernate3.SessionFactoryUtils.getNewSession(SessionFactoryUtils.java:527),位于org.springframework.orm.hibernate3.HibernateTemplate.getSession(HibernateTemplate.java:454),位于org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:393)@EaswaramoorthyKanagaraj的代码听起来像是运行在一个不是由Grails创建的线程上,因此没有上下文来创建一个线程。使用我建议的冗长且不完美的代码或Executor插件是在随机线程上实现hibernate会话的最佳方法。当我使用Domain.withNewSession时,我遇到以下异常:org.springframework.dao.DataAccessResourceFailureException:无法打开hibernate会话;嵌套异常为org.hibernate.SessionException:会话已关闭!位于org.springframework.orm.hibernate3.SessionFactoryUtils.getNewSession(SessionFactoryUtils.java:527),位于org.springframework.orm.hibernate3.HibernateTemplate.getSession(HibernateTemplate.java:454),位于org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:393)@EaswaramoorthyKanagaraj的代码听起来像是运行在一个不是由Grails创建的线程上,因此没有上下文来创建一个线程。使用我建议的冗长且不完美的代码或Executor插件是在随机线程上实现hibernate会话的最佳方法。@Burt:我还是遇到了同样的异常。这是由于多个线程之间使用相同的hibernate会话造成的吗?如果是这样的话,有没有办法在grails中增加hibernate会话的创建?我没有为hibernate配置任何东西?你能告诉我grails中hibernate的更好配置吗?不,这就是全部问题所在-hibernate会话在新线程中不可用。但是使用
with transaction
(即使您没有更新)是一个快速修复方法,因为它创建并绑定一个新会话,并在整个过程中保持加载的实例的连接。能否尝试
grails clean
并再次运行?@BurtBeckwith除非最近(2.0?)发生了变化,否则withNewSession和withTransaction都不会在新创建的线程上绑定或创建hibernate会话。这就是为什么Executor插件和它之前的后台线程插件存在的原因。不,不是真的
withTransaction
总是这样做。我经常建议将其作为解决此类问题的一种方法,即使您不更新数据库,因为创建tx是相对轻量级的
withNewSession
较新,但如果它可用,可能会更好,因为它确实绑定了sess