我正在开发一个grails应用程序(服务器)来跟踪Wi-Fi网络中的移动设备。用户将向grails应用程序(服务器)上运行的Web服务发送请求以及Mobileid和Wi-Fi IP地址。
在我的grails应用程序中,我正在查看多个外部java线程,每个线程将ping每个移动设备的Wi-Fi IP地址(每个设备要跟踪一个线程)。如果无法访问任何设备IP,那么我将从外部线程将数据库中的移动状态更新为“已断开连接”。这里只有我遇到问题,如果多个设备无法访问,那么多个线程将使用 domain.withTransaction 方法更新同一个表中每个设备的状态,而我正在获取以下异常
org.springframework.transaction.CannotCreateTransactionException:无法打开Hibernate Session进行事务处理;嵌套异常是java.lang.NullPointerException 在org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:596) 在org.codehaus.groovy.grails.orm.hibernate.GrailsHibernateTransactionManager.super $ 3 $ doBegin(GrailsHibernateTransactionManager.groovy) at sun.reflect.GeneratedMethodAccessor492.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在java.lang.reflect.Method.invoke(Method.java:597) 在org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:88) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1058) at 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天,但我无法解决这个问题。
答案 0 :(得分:3)
将读取移动到事务中,否则它们将处于断开连接的会话中,而不是事务创建的会话中。此外,最好在类上调用静态方法,而不是实例(在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()
}
}
答案 1 :(得分:1)
而不是使用Tiggerizzy建议的详细绑定代码。最好在域类上使用内置的withNewSession方法:
Mobile.withNewSession {
// your code here
}
答案 2 :(得分:0)
我不需要传播错误信息和糟糕的做事方式。 Burt和Graeme的答案都有效。我刚写了quick test app to prove this。