我正在开发一个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)
我的守则:
线程中的敲击装置
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()
}
我试了四天,但我无法解决这个问题。
发布于 2011-09-20 16:42:37
将读取移动到事务中,否则它们将处于断开连接的会话中,而不是事务创建的会话中。另外,最好调用类上的静态方法,而不是实例(在Groovy和Java中):
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()
}
}
发布于 2011-09-21 09:24:40
而不是使用Tiggerizzy建议的详细绑定代码。最好在域类上使用内置的withNewSession方法:
Mobile.withNewSession {
// your code here
}
发布于 2011-09-21 04:41:58
我没必要散布错误的信息和不良的做事方式。伯特和格雷姆的答案都会奏效。我刚写了一个快速测试应用程序来证明这一点。
https://stackoverflow.com/questions/7487866
复制相似问题