Grails的' save(flush:true)在socketRead0中挂起线程

时间:2013-02-26 17:26:15

标签: oracle hibernate grails

Grails 2.2中有一个transactional=true服务,我只做以下几点:

...
client.save(flush: true) // it hangs here
...

如果我删除flush:true,执行会进一步传递,尽管它会在稍后调用withTransaction时挂起。

我以前从未遇到过当前这个大项目的问题。

我有一个想法抛出一些flush'es和withTransaction,但这有点不受欢迎,因为目前代码中有很多它们。所以即使它能解决这个问题,也会是一个痛苦的变化。

知道如何治愈/调查吗?

Grails 2.2 / Java 1.6 / Windows 7 x64 / Oracle XE

绞死线程的堆栈跟踪:

java.net.SocketInputStream.socketRead0(Native Method)
java.net.SocketInputStream.read(SocketInputStream.java:150)
java.net.SocketInputStream.read(SocketInputStream.java:121)
oracle.net.ns.Packet.receive(Unknown Source)
oracle.net.ns.DataPacket.receive(Unknown Source)
oracle.net.ns.NetInputStream.getNextPacket(Unknown Source)
oracle.net.ns.NetInputStream.read(Unknown Source)
oracle.net.ns.NetInputStream.read(Unknown Source)
oracle.net.ns.NetInputStream.read(Unknown Source)
oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:971)
oracle.jdbc.driver.T4CMAREngine.unmarshalSB1(T4CMAREngine.java:941)
oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:432)
oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:181)
oracle.jdbc.driver.T4CPreparedStatement.execute_for_rows(T4CPreparedStatement.java:543)
oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:8674)
   - locked oracle.jdbc.driver.T4CPreparedStatement@36df36e5
   - locked oracle.jdbc.driver.T4CConnection@788d1087
org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:114)
org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:109)
org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:244)
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2412)
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2875)
org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)
org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273)
org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265)
org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)
org.codehaus.groovy.grails.orm.hibernate.events.PatchedDefaultFlushEventListener.performExecutions(PatchedDefaultFlushEventListener.java:46)
org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
org.codehaus.groovy.grails.orm.hibernate.metaclass.SavePersistentMethod.flushSession(SavePersistentMethod.java:87)
org.codehaus.groovy.grails.orm.hibernate.metaclass.SavePersistentMethod$1.doInHibernate(SavePersistentMethod.java:60)
org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:339)
org.codehaus.groovy.grails.orm.hibernate.metaclass.SavePersistentMethod.performSave(SavePersistentMethod.java:56)
org.codehaus.groovy.grails.orm.hibernate.metaclass.AbstractSavePersistentMethod.doInvokeInternal(AbstractSavePersistentMethod.java:215)
org.codehaus.groovy.grails.orm.hibernate.metaclass.AbstractDynamicPersistentMethod.invoke(AbstractDynamicPersistentMethod.java:63)
sun.reflect.GeneratedMethodAccessor662.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:601)
org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1243)
org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoCachedMethodSite.invoke(PojoMetaMethodSite.java:189)
org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:55)
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:124)
org.codehaus.groovy.grails.orm.hibernate.HibernateGormInstanceApi.save(HibernateGormEnhancer.groovy:911)
xxx.domain.Consumer.save(Consumer.groovy)
xxx.domain.Consumer$save.call(Unknown Source)
org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
xxx.UserService.createUser(UserService.groovy:350)
............

1 个答案:

答案 0 :(得分:3)

你的stacktrace指出了可能出现的问题:

oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:8674)
   - locked oracle.jdbc.driver.T4CPreparedStatement@36df36e5
   - locked oracle.jdbc.driver.T4CConnection@788d1087

您的数据库中存在卡住的线程(或线程),应用程序正在等待线程。您需要检查数据库状态以查看是否可以确定挂起的查询。可以更新到最新的JDBC驱动程序将有所帮助。

使用flush: true时发生这种情况的原因是因为它迫使你的Hibernate会话刷新到数据库,遇到卡住的线程。