首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >无法为事务打开Hibernate会话

无法为事务打开Hibernate会话
EN

Stack Overflow用户
提问于 2011-09-20 15:40:11
回答 3查看 4.6K关注 0票数 0

我正在开发一个grails应用程序(服务器)来跟踪Wi网络中的移动设备。用户将向运行在grails (服务器)上的webservice以及Mobileid和Wi地址发送请求。

在我的grails应用程序中,我正盯着多个外部java线程,每个线程都将敲击每个移动设备的will地址(每一个设备跟踪一个线程)。如果无法访问任何设备IP,我将从外部线程将移动状态更新为“断开连接”。这里只有我面临的问题,如果多个设备处于不可访问状态,那么多个线程将使用domain.withTransaction方法更新同一表中每个设备的状态,同时得到以下异常

org.springframework.transaction.CannotCreateTransactionException:不能打开Hibernate会话进行事务处理;嵌套异常是org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:596) at org.codehaus.groovy.grails.orm.hibernate.GrailsHibernateTransactionManager.super$3$doBegin(GrailsHibernateTransactionManager.groovy) at sun.reflect.GeneratedMethodAccessor492.invoke(Unknown Source) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:88)在groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1058) at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1070) at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodOnSuperN(ScriptBytecodeAdapter.java:127)

我的守则:

线程中的敲击装置

代码语言:javascript
运行
复制
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) { }

数据库中的更新状态

代码语言:javascript
运行
复制
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()
        }

我试了四天,但我无法解决这个问题。

EN

回答 3

Stack Overflow用户

发布于 2011-09-20 16:42:37

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

代码语言:javascript
运行
复制
void deviceDisconnected(String mobileId, String wifiIp){
   try {
      UserMobile.withTransaction { tx ->
         def mobile = Mobile.findByMobileId(mobileId)
         def userMobile = UserMobile.findByMobileAndWifiIp(mobile, wifiIp)
         userMobile.action = Constants.MOBILE_STATUS_DISCONNECTED
         userMobile.alarmStatus = Constants.ALARM_STATUS_TURNED_ON
         userMobile.modifiedDate = new Date()
         userMobile.save(flush: true)
      }
   }
   catch(e) {
      e.printStackTrace()
   }
}
票数 3
EN

Stack Overflow用户

发布于 2011-09-21 09:24:40

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

代码语言:javascript
运行
复制
Mobile.withNewSession {
   // your code here
}
票数 1
EN

Stack Overflow用户

发布于 2011-09-21 04:41:58

我没必要散布错误的信息和不良的做事方式。伯特和格雷姆的答案都会奏效。我刚写了一个快速测试应用程序来证明这一点

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7487866

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档