@@ -103,6 +103,7 @@ public synchronized void close() {
103103
104104 boolean isOwnerThread = nativeIsOwnerThread (transaction );
105105 if (!isOwnerThread ) {
106+ // Note: don't use isActive(), it returns false here because closed == true already
106107 boolean isActive = nativeIsActive (transaction );
107108 boolean isRecycled = nativeIsRecycled (transaction );
108109 if (isActive || isRecycled ) {
@@ -128,23 +129,31 @@ public synchronized void close() {
128129 if (!store .isNativeStoreClosed ()) {
129130 nativeDestroy (transaction );
130131 } else {
131- String threadType = isOwnerThread ? "owner thread" : "non-owner thread" ;
132- String activeInfo = isActive () ? " (active TX)" : " (inactive TX)" ;
132+ // Note: don't use isActive(), it returns false here because closed == true already
133+ boolean isActive = nativeIsActive ( transaction ) ;
133134 if (readOnly ) {
134- // Minor leak if TX is active, but still log so we can check logs that it only happens occasionally.
135- // We cannot rely on the native and Java stores waiting briefly for read transactions.
136- System .out .println ("Info: closing read transaction after store was closed (should be avoided) in " +
137- threadType + activeInfo );
135+ // Minor leak if TX is active, but still log so the ObjectBox team can check that it only happens
136+ // occasionally.
137+ // Note this cannot assume the store isn't destroyed, yet. The native and Java stores may at best
138+ // briefly wait for read transactions.
139+ System .out .printf (
140+ "Info: closing read transaction after store was closed (isActive=%s, isOwnerThread=%s), this should be avoided.%n" ,
141+ isActive , isOwnerThread );
138142 System .out .flush ();
139143
140- if (!isActive ()) { // Note: call "isActive()" for fresh value (do not cache it)
144+ // Note: get fresh active state
145+ if (!nativeIsActive (transaction )) {
141146 nativeDestroy (transaction );
142147 }
143- } else { // write transaction
144- System .out .println ("WARN: closing write transaction after store was closed (must be avoided) in " +
145- threadType + activeInfo );
148+ } else {
149+ // write transaction
150+ System .out .printf (
151+ "WARN: closing write transaction after store was closed (isActive=%s, isOwnerThread=%s), this must be avoided.%n" ,
152+ isActive , isOwnerThread );
146153 System .out .flush ();
147- if (isActive () && store .isNativeStoreDestroyed ()) { // Note: call "isActive()" for fresh value
154+
155+ // Note: get fresh active state
156+ if (nativeIsActive (transaction ) && store .isNativeStoreDestroyed ()) {
148157 // This is an internal validation: if this is an active write-TX,
149158 // the (native) store will always wait for it, so it must not be destroyed yet.
150159 // If this ever happens, the above assumption is wrong, and throwing likely prevents a SIGSEGV.
0 commit comments