import java.util.concurrent.locks.ReentrantLock;
import org.simantics.db.ChangeSet;
+import org.simantics.db.Disposable;
import org.simantics.db.Operation;
import org.simantics.db.VirtualGraph;
import org.simantics.db.common.utils.Logger;
private volatile int readCount = 0; // Must be volatile so we don't have to synchronize getReadCount.
private volatile int writeCount = 0; // Must be volatile so we don't have to synchronize getWriteCount.
private Thread writeOwner = null;
- private int asyncCount = 1;
+ private volatile int asyncCount = 1; // Must be volatile so we don't have to synchronize getAsyncCount.
private TransactionToken transactionToken = null;
void setCombine(boolean a) {
if (null != transactionToken)
void stopReadTransaction() throws DatabaseException {
lock.lock();
try {
- assert (!queryProvider.hasScheduledUpdates());
+ assert (!queryProvider.listening.hasScheduledUpdates());
assert (readCount == 1);
session.writeSupport.gc();
transactionToken.stopReadTransaction();
try {
final boolean undo = false;
if (!context.isOk(undo)) // this is a blocking operation
- throw new InternalException("Cancel failed. This should never happen. Contact application support.");
+ throw new InternalException("Cancel failed. This should never happen.");
// System.out.println("session cs: " + session.clientChanges);
// System.out.println("reverse cs: " + cs);
- queryProvider.performDirtyUpdates(graph);
- queryProvider.performScheduledUpdates(graph);
+ queryProvider.propagateChangesInQueryCache(graph);
+ queryProvider.listening.fireListeners(graph);
} catch (DatabaseException e) {
Logger.defaultLogError(e);
}
// This will send and accept the reverse change set.
transactionToken.cancelEnd(session.writeSupport, null, session.clusterStream);
+ } else {
+ queryProvider.propagateChangesInQueryCache(graph);
+ queryProvider.listening.fireListeners(graph);
}
}
session.writeSupport.clearMetadata();
if (vg != null && clusterStream.isDirty())
new Exception("Internal error: virtual transaction committed changes into core (" + request + ")").printStackTrace();
-// long start = System.nanoTime();
- if (null == vg) {
- clusterStream.reallyFlush();
- // This was fired just before in handleUpdatesAndMetadata
-// if (!writeOnly)
-// session.fireMetadataListeners(graph, cs);
- } else
- clusterStream.clear();
-
-// long duration = System.nanoTime() - start;
-// System.out.println("reallyFlush " + 1e-9*duration + "s. ");
+ // This is needed even when the write targets a virtual graph -
+ // deny can always remove a persistent statement.
+ clusterStream.reallyFlush();
session.clientChanges = new ClientChangesImpl(session);
// start = System.nanoTime();
- queryProvider.performScheduledUpdates(graph);
+ queryProvider.propagateChangesInQueryCache(graph);
+ queryProvider.listening.fireListeners(graph);
// duration = System.nanoTime() - start;
// System.out.println("performScheduledUpdates " + 1e-9*duration + "s. ");
// Process updates as long as pending primitives exist
while (session.dirtyPrimitives) {
session.dirtyPrimitives = false;
- queryProvider.performDirtyUpdates(graph);
- queryProvider.performScheduledUpdates(graph);
+ queryProvider.propagateChangesInQueryCache(graph);
+ queryProvider.listening.fireListeners(graph);
}
if (!writeOnly) // TODO: fix me! FIX ME! Please fix me! Please!
this.close(); // Everything is lost anyway.
throw new IllegalStateException(e);
} finally {
+ Disposable.safeDispose(cs);
lock.unlock();
}
}