@@ -74,6 +74,7 @@ public abstract class AbstractSailConnection implements SailConnection {
74
74
private final AbstractSail sailBase ;
75
75
76
76
private volatile boolean txnActive ;
77
+ private static final VarHandle TXN_ACTIVE ;
77
78
78
79
private volatile boolean txnPrepared ;
79
80
@@ -91,16 +92,6 @@ public abstract class AbstractSailConnection implements SailConnection {
91
92
private boolean isOpen = true ;
92
93
private static final VarHandle IS_OPEN ;
93
94
94
- static {
95
- try {
96
- IS_OPEN = MethodHandles .lookup ()
97
- .in (AbstractSailConnection .class )
98
- .findVarHandle (AbstractSailConnection .class , "isOpen" , boolean .class );
99
- } catch (ReflectiveOperationException e ) {
100
- throw new Error (e );
101
- }
102
- }
103
-
104
95
/**
105
96
* Lock used to prevent concurrent calls to update methods like addStatement, clear, commit, etc. within a
106
97
* transaction.
@@ -138,17 +129,20 @@ public abstract class AbstractSailConnection implements SailConnection {
138
129
139
130
private IsolationLevel transactionIsolationLevel ;
140
131
141
- // used to decide if we need to call flush()
132
+ // Used to decide if we need to call flush(). Use the VarHandles below in relase/acquire mode instead.
142
133
private volatile boolean statementsAdded ;
143
134
private volatile boolean statementsRemoved ;
144
135
136
+ private static final VarHandle STATEMENTS_ADDED ;
137
+ private static final VarHandle STATEMENTS_REMOVED ;
138
+
145
139
/*--------------*
146
140
* Constructors *
147
141
*--------------*/
148
142
149
143
public AbstractSailConnection (AbstractSail sailBase ) {
150
144
this .sailBase = sailBase ;
151
- txnActive = false ;
145
+ TXN_ACTIVE . setRelease ( this , false ) ;
152
146
if (debugEnabled ) {
153
147
activeIterationsDebug = new ConcurrentHashMap <>();
154
148
} else {
@@ -177,7 +171,7 @@ protected void verifyIsOpen() throws SailException {
177
171
* @throws SailException if no transaction is active.
178
172
*/
179
173
protected void verifyIsActive () throws SailException {
180
- if (!isActive ( )) {
174
+ if (!(( boolean ) TXN_ACTIVE . getAcquire ( this ) )) {
181
175
throw new SailException ("No active transaction" );
182
176
}
183
177
}
@@ -215,7 +209,7 @@ public void begin(IsolationLevel isolationLevel) throws SailException {
215
209
}
216
210
217
211
startTransactionInternal ();
218
- txnActive = true ;
212
+ TXN_ACTIVE . setRelease ( this , true ) ;
219
213
} finally {
220
214
updateLock .unlock ();
221
215
}
@@ -268,15 +262,15 @@ public final void close() throws SailException {
268
262
try {
269
263
forceCloseActiveOperations ();
270
264
271
- if (txnActive ) {
265
+ if (( boolean ) TXN_ACTIVE . getAcquire ( this ) ) {
272
266
logger .warn ("Rolling back transaction due to connection close" ,
273
267
debugEnabled ? new Throwable () : null );
274
268
try {
275
269
// Use internal method to avoid deadlock: the public
276
270
// rollback method will try to obtain a connection lock
277
271
rollbackInternal ();
278
272
} finally {
279
- txnActive = false ;
273
+ TXN_ACTIVE . setRelease ( this , false ) ;
280
274
txnPrepared = false ;
281
275
}
282
276
}
@@ -417,7 +411,7 @@ public final long size(Resource... contexts) throws SailException {
417
411
}
418
412
419
413
protected final boolean transactionActive () {
420
- return txnActive ;
414
+ return ( boolean ) TXN_ACTIVE . getAcquire ( this ) ;
421
415
}
422
416
423
417
/**
@@ -459,7 +453,7 @@ public final void prepare() throws SailException {
459
453
460
454
updateLock .lock ();
461
455
try {
462
- if (txnActive ) {
456
+ if (( boolean ) TXN_ACTIVE . getAcquire ( this ) ) {
463
457
prepareInternal ();
464
458
txnPrepared = true ;
465
459
}
@@ -489,12 +483,12 @@ public final void commit() throws SailException {
489
483
490
484
updateLock .lock ();
491
485
try {
492
- if (txnActive ) {
486
+ if (( boolean ) TXN_ACTIVE . getAcquire ( this ) ) {
493
487
if (!txnPrepared ) {
494
488
prepareInternal ();
495
489
}
496
490
commitInternal ();
497
- txnActive = false ;
491
+ TXN_ACTIVE . setRelease ( this , false ) ;
498
492
txnPrepared = false ;
499
493
}
500
494
} finally {
@@ -525,11 +519,11 @@ public final void rollback() throws SailException {
525
519
526
520
updateLock .lock ();
527
521
try {
528
- if (txnActive ) {
522
+ if (( boolean ) TXN_ACTIVE . getAcquire ( this ) ) {
529
523
try {
530
524
rollbackInternal ();
531
525
} finally {
532
- txnActive = false ;
526
+ TXN_ACTIVE . setRelease ( this , false ) ;
533
527
txnPrepared = false ;
534
528
}
535
529
} else {
@@ -553,7 +547,8 @@ public final void addStatement(Resource subj, IRI pred, Value obj, Resource... c
553
547
flushPendingUpdates ();
554
548
}
555
549
addStatement (null , subj , pred , obj , contexts );
556
- statementsAdded = true ;
550
+
551
+ STATEMENTS_ADDED .setRelease (this , true );
557
552
}
558
553
559
554
@ Override
@@ -562,7 +557,7 @@ public final void removeStatements(Resource subj, IRI pred, Value obj, Resource.
562
557
flushPendingUpdates ();
563
558
}
564
559
removeStatement (null , subj , pred , obj , contexts );
565
- statementsRemoved = true ;
560
+ STATEMENTS_REMOVED . setRelease ( this , true ) ;
566
561
}
567
562
568
563
@ Override
@@ -604,7 +599,7 @@ public void addStatement(UpdateContext op, Resource subj, IRI pred, Value obj, R
604
599
startUpdate (op );
605
600
}
606
601
}
607
- statementsAdded = true ;
602
+ STATEMENTS_ADDED . setRelease ( this , true ) ;
608
603
}
609
604
610
605
/**
@@ -632,7 +627,7 @@ public void removeStatement(UpdateContext op, Resource subj, IRI pred, Value obj
632
627
startUpdate (op );
633
628
}
634
629
}
635
- statementsRemoved = true ;
630
+ STATEMENTS_REMOVED . setRelease ( this , true ) ;
636
631
}
637
632
638
633
@ Override
@@ -703,7 +698,7 @@ public final void clear(Resource... contexts) throws SailException {
703
698
try {
704
699
verifyIsActive ();
705
700
clearInternal (contexts );
706
- statementsRemoved = true ;
701
+ STATEMENTS_REMOVED . setRelease ( this , true ) ;
707
702
} finally {
708
703
updateLock .unlock ();
709
704
}
@@ -836,19 +831,20 @@ public final void clearNamespaces() throws SailException {
836
831
837
832
@ Override
838
833
public boolean pendingRemovals () {
839
- return statementsRemoved ;
834
+ return (boolean ) STATEMENTS_REMOVED .getAcquire (this );
835
+
840
836
}
841
837
842
838
protected boolean pendingAdds () {
843
- return statementsAdded ;
839
+ return ( boolean ) STATEMENTS_ADDED . getAcquire ( this ) ;
844
840
}
845
841
846
842
protected void setStatementsAdded () {
847
- statementsAdded = true ;
843
+ STATEMENTS_ADDED . setRelease ( this , true ) ;
848
844
}
849
845
850
846
protected void setStatementsRemoved () {
851
- statementsRemoved = true ;
847
+ STATEMENTS_REMOVED . setRelease ( this , true ) ;
852
848
}
853
849
854
850
@ Deprecated (forRemoval = true )
@@ -992,9 +988,10 @@ private void forceCloseActiveOperations() throws SailException {
992
988
* @throws SailException
993
989
*/
994
990
private void flushPendingUpdates () throws SailException {
995
- if ((statementsAdded || statementsRemoved ) && isActive ()) {
991
+ if ((pendingAdds () || pendingRemovals () ) && isActive ()) {
996
992
if (isActive ()) {
997
993
synchronized (this ) {
994
+ // we are inside a synchornized block so there isn't much point using the VarHandle
998
995
if ((statementsAdded || statementsRemoved ) && isActive ()) {
999
996
flush ();
1000
997
statementsAdded = false ;
@@ -1128,4 +1125,44 @@ public synchronized void release() {
1128
1125
}
1129
1126
}
1130
1127
}
1128
+
1129
+ static {
1130
+ try {
1131
+ IS_OPEN = MethodHandles .lookup ()
1132
+ .in (AbstractSailConnection .class )
1133
+ .findVarHandle (AbstractSailConnection .class , "isOpen" , boolean .class );
1134
+ } catch (ReflectiveOperationException e ) {
1135
+ throw new Error (e );
1136
+ }
1137
+ }
1138
+
1139
+ static {
1140
+ try {
1141
+ TXN_ACTIVE = MethodHandles .lookup ()
1142
+ .in (AbstractSailConnection .class )
1143
+ .findVarHandle (AbstractSailConnection .class , "txnActive" , boolean .class );
1144
+ } catch (ReflectiveOperationException e ) {
1145
+ throw new Error (e );
1146
+ }
1147
+ }
1148
+
1149
+ static {
1150
+ try {
1151
+ STATEMENTS_REMOVED = MethodHandles .lookup ()
1152
+ .in (AbstractSailConnection .class )
1153
+ .findVarHandle (AbstractSailConnection .class , "statementsRemoved" , boolean .class );
1154
+ } catch (ReflectiveOperationException e ) {
1155
+ throw new Error (e );
1156
+ }
1157
+ }
1158
+
1159
+ static {
1160
+ try {
1161
+ STATEMENTS_ADDED = MethodHandles .lookup ()
1162
+ .in (AbstractSailConnection .class )
1163
+ .findVarHandle (AbstractSailConnection .class , "statementsAdded" , boolean .class );
1164
+ } catch (ReflectiveOperationException e ) {
1165
+ throw new Error (e );
1166
+ }
1167
+ }
1131
1168
}
0 commit comments