Configuring Dirty Reads

You can configure JE to use degree 1 isolation (see Transactions and Concurrency) by configuring it to perform dirty reads. Dirty reads allows a reader to see modifications made but not committed by a transaction in which the read is not being performed.

Dirty reads can improve your application's performance by avoiding lock contention between the reader and other threads that are writing to the database. However, they are also dangerous because there is a possibility that the data returned as a part of a dirty read will disappear as the result of an abort on the part of the transaction who is holding the write lock.

Concurrency and transactions are described in more detail in Transactions and Concurrency

You can configure the default dirty read behavior for a transaction using TransactionConfig.setDirtyRead():

import com.sleepycat.je.Transaction;
import com.sleepycat.je.TransactionConfig;

...
// Environment and database open omitted
...

try {
    TransactionConfig tc = new TransactionConfig();
    tc.setDirtyRead(true); // Dirty reads will be performed
    Transaction txn = myEnv.beginTransaction(null, tc);

    DatabaseEntry theKey = 
        new DatabaseEntry((new String("theKey")).getBytes("UTF-8"));
    DatabaseEntry theData = new DatabaseEntry();

    myDatabase.get(txn, theKey, theData, LockMode.DEFAULT); 
} catch (Exception e) {
    // Exception handling goes here
}

You can also configure the dirty read behavior on a read-by-read basis by specifying LockMode.DIRTY_READ:

import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.LockMode;
import com.sleepycat.je.Transaction;

...
// Environment and database open omitted
...

try {
    Transaction txn = myEnv.beginTransaction(null, null);

    DatabaseEntry theKey = 
        new DatabaseEntry((new String("theKey")).getBytes("UTF-8"));
    DatabaseEntry theData = new DatabaseEntry();

    myDatabase.get(txn, theKey, theData, LockMode.DIRTY_READ);
} catch (Exception e) {
    // Exception handling goes here
} 

When using cursors, you can specify the dirty read behavior as described above, or you can specify it using CursorConfig.setDirtyRead():

import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.Cursor;
import com.sleepycat.je.CursorConfig;
import com.sleepycat.je.Transaction;
import com.sleepycat.je.LockMode;

...   
// Environment and database opens omitted for brevity
...

try {
    DatabaseEntry theKey = 
        new DatabaseEntry((new String("theKey")).getBytes("UTF-8"));
    DatabaseEntry theData = new DatabaseEntry();

    // Start a transaction
    Transaction txn = myEnv.beginTransaction(null, null);

    // Open a cursor using the transaction
    CursorConfig cc = new CursorConfig();
    cc.setDirtyRead(true);                    // Perform dirty reads
    Cursor cursor = myDatabase.openCursor(txn, cc);
 
    cursor.getSearchKey(theKey, theData, LockMode.DEFAULT); 
} catch (Exception e) {
    // Exception handling goes here
}