Snapshot mode allows you to get the advantages of the Lazy queries avoiding their side effects. When query is executed, the query processor chooses the best indexes, does all index processing and creates a snapshot of the index at this point in time. Non-indexed constraints are evaluated lazily when the application iterates through the ObjectSet
resultset of the query.
01private static void testSnapshotQueries() { 02
System.out 03
.println("Testing query performance on 10000 pilot objects in Snapshot mode"); 04
fillUpDB(10000); 05
Configuration configuration = Db4o.newConfiguration(); 06
configuration.queries().evaluationMode(QueryEvaluationMode.SNAPSHOT); 07
ObjectContainer container = Db4o.openFile(configuration, DB4O_FILE_NAME); 08
try { 09
QueryStats stats = new QueryStats(); 10
stats.connect(container); 11
Query query = container.query(); 12
query.constrain(Pilot.class); 13
query.descend("points").constrain(99).greater(); 14
query.execute(); 15
long executionTime = stats.executionTime(); 16
System.out.println("Query execution time: " 17
+ executionTime); 18
} finally { 19
container.close(); 20
} 21
}
Snapshot queries ensure better performance than Immediate queries, but the performance will depend on the size of the resultset.
As the snapshot of the results is kept in memory the result set is not affected by the changes from the caller or from another transaction (compare the results of this code snippet to the one from Lazy Queries topic):
01private static void testSnapshotConcurrent() { 02
System.out 03
.println("Testing snapshot mode with concurrent modifications"); 04
fillUpDB(10); 05
Configuration configuration = Db4o.newConfiguration(); 06
configuration.queries().evaluationMode(QueryEvaluationMode.SNAPSHOT); 07
ObjectContainer container = Db4o.openFile(configuration, DB4O_FILE_NAME); 08
try { 09
Query query1 = container.query(); 10
query1.constrain(Pilot.class); 11
query1.descend("points").constrain(5).smaller(); 12
ObjectSet result1 = query1.execute(); 13
14
Query query2 = container.query(); 15
query2.constrain(Pilot.class); 16
query2.descend("points").constrain(1); 17
ObjectSet result2 = query2.execute(); 18
Pilot pilotToDelete = (Pilot) result2.get(0); 19
System.out.println("Pilot to be deleted: " 20
+ pilotToDelete); 21
container.delete(pilotToDelete); 22
Pilot pilot = new Pilot("Tester", 2); 23
System.out.println("Pilot to be added: " + pilot); 24
container.set(pilot); 25
26
System.out 27
.println("Query result after changing from the same transaction"); 28
listResult(result1); 29
} finally { 30
container.close(); 31
} 32
}
Pros:
Cons:
Client/Server applications with the risk of concurrent modifications should prefer Snapshot mode to avoid side effects from other transactions.