我正在開發一個Grails應用程序(服務器)來跟蹤Wi-Fi網絡中的移動設備。用戶將向在grails應用程序(服務器)上運行的web服務發送請求以及Mobileid和Wi-Fi IP地址。無法打開Hibernate Session進行交易
在我的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作爲) 在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天,但我無法解決這個問題。
@伯特:我仍得到相同的異常。是否由於在多個線程之間使用相同的hibernate會話?如果是這樣,是否有任何方法來增加在grails中創建hibernate會話?我沒有配置任何東西休眠?你能告訴我在grails中更好的配置hibernate嗎? –
不,這是整個問題 - Hibernate會話在新線程中不可用。但是使用'withTransaction'(即使你沒有更新)是一個快速的修復,因爲它創建和綁定了一個新的會話,並且在持續時間內保持已加載的實例的連接。你可以試試'grails clean'並再次運行? –
@BurtBeckwith除非事件最近(2.0?)發生更改,否則NewSession和withTransaction都不會在新創建的線程上綁定或創建一個hibernate會話。這就是Executor Plugin和之前的Background Thread插件存在的原因。 –