私はいくつかの (長時間実行される) 処理を行っているトランザクション Grails サービスを持っています。処理中に、「percentComplete」値を更新したいと思います (最終的には、フロントエンドに進行状況バーを表示するために使用されます)。これは明らかにすぐに書き込む必要があります (つまり、現在のトランザクションの一部としてではありません)。そうしないと、価値がありません。
したがって、私はGrails トランザクション処理プラグインを使用し、具体的には "withNewTransaction" メソッドを使用して新しいトランザクションを開始し、その中で percentComplete 属性が更新されます。
私の問題は、「updatePercentComplete()」メソッドの 2 回目で、「withNewTransaction」メソッドを終了しようとすると (おそらくトランザクションをコミットしようとしているとき)、アプリケーションがハングすることです。
ノート:
- メイン サービス メソッドでセッション フラッシュをコメント アウトしても問題はありません (実際のアプリケーションではパフォーマンス上の理由から、このフラッシュとクリアが必要です)
- hsql データベースを使用する場合、問題はありません (DataSources.groovy を参照)。
- また、grails executor プラグインを使用していますが、これ自体が問題を引き起こしているとは思いません (LibraryServiceTests も参照してください。これもハングしてプラグインをバイパスします)。
この問題をデバッグするにはどこに行けばよいですか? 何が起こっているのかを特定するために、grails/hibernate のどこかに設定できるログレベルがいくつかあるのではないでしょうか?
作業を行っているスレッドがソケットから読み取ろうとしてスタックしているようです。以下のスタック トレースを参照してください。JVM 自体に実際のデッドロックはないようです。
これが私のサービスクラスです。以下の完全なプロジェクトへのリンク:
package withtransactiontest
class LibraryService {
static transactional = true
def sessionFactory
def loadBooks(library) {
int repeat = 5
repeat.times {
updatePercentComplete(library, it * (100 / repeat))
// Simulate some long running process in order to be able to see percentComplete getting written to DB.
Thread.sleep(2000)
// Update some property (within the default transaction)
library.name += "x"
library.save()
// Comment out the following, and the current method will complete successfully.
def session = sessionFactory?.currentSession
session?.flush()
}
library.percentComplete = 100
library.save()
}
void updatePercentComplete(library, val) {
println "before new transaction"
Library.withNewTransaction {
println "Percent complete: " + val
library.refresh()
library.percentComplete = val
library.save()
println "after save"
// Hang here, second time around.
}
println "Percent complete transaction committed"
library.refresh()
}
}
問題を再現する統合テスト ケースを含む Grails プロジェクトへのリンク
「ワーカー」スレッドのスタックトレース:
スレッド [pool-1-thread-1] (中断)
SocketInputStream.socketRead0(FileDescriptor, byte[], int, int, int) 行: 利用不可 [ネイティブメソッド]
SocketInputStream.read(byte[], int, int) 行: 129
ReadAheadInputStream.fill(int) 行: 114
ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(byte[], int, int) 行: 161
ReadAheadInputStream.read(byte[], int, int) 行: 189
MysqlIO.readFully(Input, byte[] , int, int) 行: 2499 MysqlIO.reuseAndReadPacket(Buffer, int) 行: 2952
MysqlIO.reuseAndReadPacket(Buffer) 行: 2941
MysqlIO.checkErrorPacket(int) 行: 3489
MysqlIO.sendCommand(int, String, Buffer, boolean, String 、int) 行: 1959
MysqlIO.sqlQueryDirect(StatementImpl, String, String, Buffer, int, int, int, boolean, String, Field[]) 行: 2113
JDBC4Connection(ConnectionImpl).execSQL(StatementImpl, String, int, Buffer, int, int, boolean, String, Field[], boolean) 行: 2568 JDBC4PreparedStatement(PreparedStatement).executeInternal(int, Buffer, boolean, boolean, Field[], boolean) 行: 2113
JDBC4PreparedStatement(PreparedStatement).executeUpdate(byte[][], InputStream[ ], boolean[], int[], boolean[], boolean) 行: 2409
JDBC4PreparedStatement(PreparedStatement).executeUpdate(boolean, boolean) 行: 2327
JDBC4PreparedStatement(PreparedStatement).executeUpdate() 行: 2312
DelegatingPreparedStatement.executeUpdate() 行:105
DelegatingPreparedStatement.executeUpdate() 行: 105
GroovyAwareSingleTableEntityPersister(AbstractEntityPersister).update(Serializable, Object[], Object[], Object, boolean[], int, Object, Object, String, SessionImplementor) 行: 2435
GroovyAwareSingleTableEntityPersister(AbstractEntityPersister).updateOrInsert (Serializable, Object[], Object[], Object, boolean[], int, Object, Object, String, SessionImplementor) 行: 2335
GroovyAwareSingleTableEntityPersister(AbstractEntityPersister).update(Serializable, Object[], int[], boolean, Object []、オブジェクト、オブジェクト、オブジェクト、SessionImplementor) 行: 2635
EntityUpdateAction.execute() 行: 115
ActionQueue.execute(実行可能) 行: 279
ActionQueue.executeActions(リスト) 行: 263
ActionQueue.executeActions() 行: 168
PatchedDefaultFlushEventListener.performExecutions(EventSource) 行: 46
PatchedDefaultFlushEventListener(DefaultFlushEventListener).onFlush(FlushEvent) 行: 50
SessionImpl.flush() 行: 1027
SessionImpl.managedFlush() 行: 365
JDBCTransaction.commit()行: 137
GrailsHibernateTransactionManager(HibernateTransactionManager).doCommit(DefaultTransactionStatus) 行: 656 GrailsHibernateTransactionManager(AbstractPlatformTransactionManager).processCommit(DefaultTransactionStatus) 行: 754 GrailsHibernateTransactionManager(AbstractPlatformTransactionManager).commit(TransactionStatus) 行: 723
TransactionTemplate.execute(TransactionCallback) 行: 147
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) 行: 利用不可 [ネイティブメソッド]
NativeMethodAccessorImpl.invoke(Object, Object[]) 行: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) 行: 25
Method.invoke( Object, Object...) 行: 597
PojoMetaMethodSite$PojoCachedMethodSite.invoke(Object, Object[]) 行: 188
PojoMetaMethodSite$PojoCachedMethodSite(PojoMetaMethodSite).call(Object, Object[]) 行: 52 PojoMetaMethodSite$PojoCachedMethodSite(AbstractCallSite). call(Object, Object) 行: 124
GroovyDynamicMethods$_doWith_closure1.doCall(Map, Map, Closure) 行: 55
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) 行: 利用不可 [ネイティブメソッド]
NativeMethodAccessorImpl.invoke(Object, Object[]) 行: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) 行: 25
Method.invoke(Object, Object...) 行: 597
PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(Object, Object[ ]) 行: 266
PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce(PogoMetaMethodSite).callCurrent(GroovyObject, Object[]) 行: 51
PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce(AbstractCallSite).callCurrent(GroovyObject, Object, Object, Object) 行: 157
GroovyDynamicMethodMap($_doWith_closure1 . , Map, Closure) 行: 利用不可
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) 行: 利用不可 [ネイティブメソッド]
NativeMethodAccessorImpl.invoke(Object, Object[]) 行: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) 行: 25
Method.invoke(Object, Object...) 行: 597
PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(Object, Object[ ]) 行: 266
PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce(PogoMetaMethodSite).call(Object, Object[]) 行: 63 PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce(AbstractCallSite).call(Object, Object, Object, Object) 行: 132
GroovyDynamicMethods$_doWith_closure3.doCall(Map , Closure) 行: 65 NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) 行: 利用不可 [ネイティブ メソッド]
NativeMethodAccessorImpl.invoke(Object, Object[]) 行: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) 行: 25
Method.invoke(Object, Object...) 行: 597
PogoMetaMethodSite$PogoCachedMethodSite.invoke(Object, Object[]) 行: 225
PogoMetaMethodSite$PogoCachedMethodSite(PogoMetaMethodSite).callCurrent (GroovyObject, Object[]) 行: 51
PogoMetaMethodSite$PogoCachedMethodSite(AbstractCallSite).callCurrent(GroovyObject, Object, Object) 行: 153
GroovyDynamicMethods$_doWith_closure3.doCall(Closure) 行: 利用不可
NativeMethodAccessorImpl.invoke0(Method, Object, Object[ ]) 行: 利用不可 [ネイティブ メソッド]
NativeMethodAccessorImpl.invoke(Object, Object[]) 行: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) 行: 25
Method.invoke(Object, Object...) 行: 597
CachedMethod.invoke(Object, Object[]) 行: 90
CachedMethod(MetaMethod).doMethodInvoke(Object, Object[]) 行: 233 ExpandoMetaClass(MetaClassImpl).invokeMethod( Class, Object, String, Object[], boolean, boolean) 行: 1058
ExpandoMetaClass.invokeMethod(Class, Object, String, Object[], boolean, boolean) 行: 1070 ExpandoMetaClass(MetaClassImpl).invokeMethod(Object, String, Object []) 行: 886
GroovyDynamicMethods$_doWith_closure3(Closure).call(Object[]) 行: 282 ClosureStaticMetaMethod.invoke(Object, Object[]) 行: 59
StaticMetaMethodSite$StaticMetaMethodSiteNoUnwrapNoCoerce.invoke(Object, Object[]) 行: 148
StaticMetaMethodSite$StaticMetaMethodSiteNoUnwrapNoCoerce(StaticMetaMethodSite).call(Object, Object[]) 行: 88 StaticMetaMethodSite$StaticMetaMethodSiteNoUnwrapNoCoerce(AbstractCallSite).call(Object, Object) 行: 124
LibraryService.updatePercentComplete(Object, Object) 行: 34
NativeMethodAccessorImpl.invoke0(Method , Object, Object[]) 行: 利用不可 [ネイティブメソッド]
NativeMethodAccessorImpl.invoke(Object, Object[]) 行: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) 行: 25
Method.invoke(Object, Object.. .) 行: 597
CachedMethod.invoke(Object, Object[]) 行: 90
CachedMethod(MetaMethod).doMethodInvoke(Object, Object[]) 行: 233 ExpandoMetaClass(MetaClassImpl).invokeMethod(Class, Object, String, Object[], boolean, boolean) 行: 1058
ExpandoMetaClass.invokeMethod(Class, Object, String, Object[], boolean, boolean) 行: 1070 ExpandoMetaClass(MetaClassImpl).invokeMethod(Object, String, Object[]) 行: 886
ExpandoMetaClass(MetaClassImpl).invokeMethod(Class, Object, String, Object[], boolean, boolean)行: 1003
ExpandoMetaClass.invokeMethod(Class, Object, String, Object[], boolean, boolean) 行: 1070 ExpandoMetaClass(MetaClassImpl).invokeMethod(Object, String, Object[]) 行: 886
PogoMetaClassSite.callCurrent(GroovyObject, Object[ ]) 行: 66
PogoMetaClassSite(AbstractCallSite).callCurrent(GroovyObject, Object, Object) 行: 153 LibraryService$_loadBooks_closure1.doCall(Object) 行: 13
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) 行: 利用不可 [ネイティブメソッド]
NativeMethodAccessorImpl.invoke (Object, Object[]) 行: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) 行: 25
Method.invoke(Object, Object...) 行: 597
CachedMethod.invoke(Object, Object[]) 行: 90
CachedMethod(MetaMethod).doMethodInvoke(Object, Object[]) 行: 233 ExpandoMetaClass(MetaClassImpl).invokeMethod(Class, Object, String, Object[], boolean, boolean) 行: 1058
ExpandoMetaClass.invokeMethod(Class, Object, String, Object[], boolean, boolean) 行: 1070 ExpandoMetaClass(MetaClassImpl).invokeMethod(Object, String, Object[]) 行: 886
LibraryService$_loadBooks_closure1(Closure).call(Object[ ]) 行: 282
LibraryService$_loadBooks_closure1(Closure).call(Object) 行: 295
DefaultGroovyMethods.times(Number, Closure) 行: 9487
dgm$630.invoke(Object, Object[]) 行: 利用不可
PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke (Object, Object[]) 行: 270
PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce(PojoMetaMethodSite).call(Object, Object[]) 行: 52
PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce(AbstractCallSite).call(Object, Object) 行: 124
LibraryService.loadBooks(Object) 行: 12
LibraryService$$FastClassByCGLIB$$f97d911e.invoke(int, Object, Object[]) 行: 利用不可
MethodProxy.invoke(Object, Object[]) 行: 149
Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint( ) 行: 688
Cglib2AopProxy$CglibMethodInvocation(ReflectiveMethodInvocation).proceed() 行: 150
TransactionInterceptor.invoke(MethodInvocation) 行: 110
Cglib2AopProxy$CglibMethodInvocation(ReflectiveMethodInvocation).proceed() 行: 172
Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Object, Method, Object[], MethodProxy) 行: 621 LibraryService$$EnhancerByCGLIB$$c098c6ba.loadBooks(Object) 行: 利用不可 LibraryService$loadBooks.call(Object, Object) 行: 利用不可
LibraryController $_closure4_closure9.doCall(Object) 行: 30
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) 行: 利用不可 [ネイティブメソッド]
NativeMethodAccessorImpl.invoke(Object, Object[]) 行: 39
DelegatingMethodAccessorImpl.invoke(Object, Object []) 行: 25
Method.invoke(Object, Object...) 行: 597
PogoMetaMethodSite$PogoCachedMethodSite.invoke(Object, Object[]) 行: 225
PogoMetaMethodSite$PogoCachedMethodSite(PogoMetaMethodSite).callCurrent(GroovyObject, Object[]) 行: 51
PogoMetaMethodSite$PogoCachedMethodSite(AbstractCallSite).callCurrent(GroovyObject, Object) 行: 149
LibraryController$_closure4_closure9.doCall() 行: 利用不可
NativeMethodAccessorImpl.invoke0(Method , Object, Object[]) 行: 利用不可 [ネイティブメソッド]
NativeMethodAccessorImpl.invoke(Object, Object[]) 行: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) 行: 25
Method.invoke(Object, Object.. .) 行: 597
CachedMethod.invoke(Object, Object[]) 行: 90
CachedMethod(MetaMethod).doMethodInvoke(Object, Object[]) 行: 233 ExpandoMetaClass(MetaClassImpl).invokeMethod(Class, Object, String, Object[], boolean, boolean) 行: 1058
ExpandoMetaClass.invokeMethod(Class, Object, String, Object[], boolean, boolean) 行: 1070 ExpandoMetaClass(MetaClassImpl).invokeMethod(Object, String, Object[]) 行: 886
LibraryController$_closure4_closure9(Closure).call(Object[]) 行: 282
ConvertedClosure.invokeCustom(Object , Method, Object[]) 行: 51
ConvertedClosure(ConversionHandler).invoke(Object, Method, Object[]) 行: 82
$Proxy6.call() 行: 利用不可
java_util_concurrent_Callable$call.call(Object) 行: 利用不可 PersistenceContextCallableWrapper$_call_closure1.doCall(Object) 行: 36
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) 行: 利用不可 [ネイティブ メソッド]
NativeMethodAccessorImpl.invoke(Object, Object) []) 行: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) 行: 25
Method.invoke(Object, Object...) 行: 597
PogoMetaMethodSite$PogoCachedMethodSite.invoke(Object, Object[]) 行: 225
PogoMetaMethodSite$ PogoCachedMethodSite(PogoMetaMethodSite).callCurrent(GroovyObject, Object[]) 行: 51
PogoMetaMethodSite$PogoCachedMethodSite(AbstractCallSite).callCurrent(GroovyObject, Object) 行: 149
PersistenceContextCallableWrapper$_call_closure1.doCall() 行: 利用不可
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) 行: 利用不可 [ネイティブ メソッド]
NativeMethodAccessorImpl.invoke(Object, Object[]) 行: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) 行: 25
Method.invoke(Object, Object...) 行: 597
CachedMethod.invoke(Object, Object[]) 行: 90
CachedMethod(MetaMethod).doMethodInvoke(Object, Object[]) 行: 233 ExpandoMetaClass(MetaClassImpl).invokeMethod(Class, Object, String, Object[], boolean, boolean) 行: 1058
ExpandoMetaClass.invokeMethod(Class, Object, String, Object[], boolean, boolean) 行: 1070 ExpandoMetaClass(MetaClassImpl).invokeMethod(Object, String, Object[]) 行: 886
PersistenceContextCallableWrapper$_call_closure1(Closure).call(Object[ ]) 行: 282
PersistenceContextCallableWrapper$_call_closure1(Closure).call() 行: 277
Closure$call.call(Object) 行: 利用不可
PersistenceContextCallableWrapper(PersistenceContextWrapper).wrap(Closure) 行:
35 Object[]) 行: 利用不可 [ネイティブ メソッド]
NativeMethodAccessorImpl.invoke(Object, Object[]) 行: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) 行: 25
Method.invoke(Object, Object...) 行: 597
PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(Object, Object[]) 行: 266
PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce(PogoMetaMethodSite).callCurrent(GroovyObject, Object[]) 行: 51
PogoMetaMethodSite$PogoCachedMethodCoerNoceerNoce (AbstractCallSite).callCurrent(GroovyObject, Object) 行: 149
PersistenceContextCallableWrapper.call() 行: 36
FutureTask$Sync.innerRun() 行: 303
FutureTask.run() 行: 138
ThreadPoolExecutor$Worker.runTask(Runnable) 行: 886
ThreadPoolExecutor$Worker.run() 行: 908
Thread.run() 行: 680