Non-Durable Transactions

As previously noted, by default transaction commits are durable because they cause the modifications performed under the transaction to be synchronously recorded in your on-disk log files. However, it is possible to use non-durable transactions.

You may want non-durable transactions for performance reasons. For example, you might be using transactions simply for the isolation guarantee. In this case, you might want to relax the synchronized write to disk that JE normally performs as part of a transaction commit. Doing so means that your data will still make it to disk; however, your application will not necessarily have to wait for the disk I/O to complete before it can perform another database operation. This can greatly improve throughput for some workloads.

To relax the durability guarantee for your transactions, you use the Durability class to define the durability policy that you want to use. The Durability class constructor takes three arguments, only one of which is interesting for a standalone transactional application:

We describe JE High Availability Applications in the Berkeley DB, Java Edition Getting Started with High Availability Applications guide.

The synchronization policy that you give the Durability class constructor can be one of the following:

You can specify your durability policy on an environment-wide basis by creating a Durability class and then giving it to EnvironmentConfig.setDurability(). You can also override the environment default durability policy on a transaction-by-transaction basis by providing a Durability class to the TransactionConfig object you use to configure your transaction using the TransactionConfig.setDurability() method.

For example:

package je.txn;

import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Durability;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.Transaction;
import com.sleepycat.je.TransactionConfig;

import java.io.File;

...

Database myDatabase = null;
Environment myEnv = null;
try {
    Durability defaultDurability = 
        new Durability(Durability.SyncPolicy.NO_SYNC, 
                       null,    // unused by non-HA applications. 
                       null);   // unused by non-HA applications.  

    EnvironmentConfig myEnvConfig = new EnvironmentConfig();
    myEnvConfig.setTransactional(true);
    myEnvConfig.setDurability(defaultDurability);
    myEnv = new Environment(new File("/my/env/home"),
                              myEnvConfig);

    // Open the database. Create it if it does not already exist.
    DatabaseConfig dbConfig = new DatabaseConfig();
    dbConfig.setTransactional(true);
    myDatabase = myEnv.openDatabase(null,
                                    "sampleDatabase",
                                    dbConfig);

    String keyString = "thekey";
    String dataString = "thedata";
    DatabaseEntry key = 
        new DatabaseEntry(keyString.getBytes("UTF-8"));
    DatabaseEntry data = 
        new DatabaseEntry(dataString.getBytes("UTF-8"));

    Durability newDurability = 
        new Durability(Durability.SyncPolicy.WRITE_NO_SYNC, 
                       null,    // unused by non-HA applications. 
                       null);   // unused by non-HA applications.

    TransactionConfig tc = new TransactionConfig();
    tc.setDurability(newDurability);
    Transaction txn = myEnv.beginTransaction(null, tc);
        
    try {
        myDatabase.put(txn, key, data);
        txn.commit();
    } catch (Exception e) {
        if (txn != null) {
            txn.abort();
            txn = null;
        }
    }

} catch (DatabaseException de) {
    // Exception handling goes here
}