summaryrefslogtreecommitdiff
path: root/examples_java/src/persist/txn
diff options
context:
space:
mode:
Diffstat (limited to 'examples_java/src/persist/txn')
-rw-r--r--examples_java/src/persist/txn/PayloadDataEntity.java33
-rw-r--r--examples_java/src/persist/txn/StoreWriter.java176
-rw-r--r--examples_java/src/persist/txn/TxnGuideDPL.java162
3 files changed, 371 insertions, 0 deletions
diff --git a/examples_java/src/persist/txn/PayloadDataEntity.java b/examples_java/src/persist/txn/PayloadDataEntity.java
new file mode 100644
index 0000000..9d464ff
--- /dev/null
+++ b/examples_java/src/persist/txn/PayloadDataEntity.java
@@ -0,0 +1,33 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2008-2009 Oracle. All rights reserved.
+ *
+ * $Id$
+ */
+
+package persist.txn;
+
+import com.sleepycat.persist.model.Entity;
+import com.sleepycat.persist.model.PrimaryKey;
+import static com.sleepycat.persist.model.Relationship.*;
+
+@Entity
+public class PayloadDataEntity {
+ @PrimaryKey
+ private int oID;
+
+ private String threadName;
+
+ private double doubleData;
+
+ PayloadDataEntity() {}
+
+ public double getDoubleData() { return doubleData; }
+ public int getID() { return oID; }
+ public String getThreadName() { return threadName; }
+
+ public void setDoubleData(double dd) { doubleData = dd; }
+ public void setID(int id) { oID = id; }
+ public void setThreadName(String tn) { threadName = tn; }
+}
diff --git a/examples_java/src/persist/txn/StoreWriter.java b/examples_java/src/persist/txn/StoreWriter.java
new file mode 100644
index 0000000..fb8b4e5
--- /dev/null
+++ b/examples_java/src/persist/txn/StoreWriter.java
@@ -0,0 +1,176 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2008-2009 Oracle. All rights reserved.
+ *
+ * $Id$
+ */
+
+package persist.txn;
+
+import com.sleepycat.db.CursorConfig;
+import com.sleepycat.db.DatabaseException;
+import com.sleepycat.db.DeadlockException;
+import com.sleepycat.db.Environment;
+import com.sleepycat.db.Transaction;
+
+import com.sleepycat.persist.EntityCursor;
+import com.sleepycat.persist.EntityStore;
+import com.sleepycat.persist.PrimaryIndex;
+
+import java.util.Iterator;
+import java.util.Random;
+import java.io.UnsupportedEncodingException;
+
+public class StoreWriter extends Thread
+{
+ private EntityStore myStore = null;
+ private Environment myEnv = null;
+ private PrimaryIndex<Integer,PayloadDataEntity> pdKey;
+ private Random generator = new Random();
+ private boolean passTxn = false;
+
+
+ private static final int MAX_RETRY = 20;
+
+ // Constructor. Get our handles from here
+ StoreWriter(Environment env, EntityStore store)
+
+ throws DatabaseException {
+ myStore = store;
+ myEnv = env;
+
+ // Open the data accessor. This is used to store persistent
+ // objects.
+ pdKey = myStore.getPrimaryIndex(Integer.class,
+ PayloadDataEntity.class);
+ }
+
+ // Thread method that writes a series of objects
+ // to the store using transaction protection.
+ // Deadlock handling is demonstrated here.
+ public void run () {
+ Transaction txn = null;
+
+ // Perform 50 transactions
+ for (int i=0; i<50; i++) {
+
+ boolean retry = true;
+ int retry_count = 0;
+ // while loop is used for deadlock retries
+ while (retry) {
+ // try block used for deadlock detection and
+ // general exception handling
+ try {
+
+ // Get a transaction
+ txn = myEnv.beginTransaction(null, null);
+
+ // Write 10 PayloadDataEntity objects to the
+ // store for each transaction
+ for (int j = 0; j < 10; j++) {
+ // Instantiate an object
+ PayloadDataEntity pd = new PayloadDataEntity();
+
+ // Set the Object ID. This is used as the primary key.
+ pd.setID(i + j);
+
+ // The thread name is used as a secondary key, and
+ // it is retrieved by this class's getName() method.
+ pd.setThreadName(getName());
+
+ // The last bit of data that we use is a double
+ // that we generate randomly. This data is not
+ // indexed.
+ pd.setDoubleData(generator.nextDouble());
+
+ // Do the put
+ pdKey.put(txn, pd);
+ }
+
+ // commit
+ System.out.println(getName() + " : committing txn : " + i);
+ System.out.println(getName() + " : Found " +
+ countObjects(txn) + " objects in the store.");
+ try {
+ txn.commit();
+ txn = null;
+ } catch (DatabaseException e) {
+ System.err.println("Error on txn commit: " +
+ e.toString());
+ }
+ retry = false;
+
+ } catch (DeadlockException de) {
+ System.out.println("################# " + getName() +
+ " : caught deadlock");
+ // retry if necessary
+ if (retry_count < MAX_RETRY) {
+ System.err.println(getName() +
+ " : Retrying operation.");
+ retry = true;
+ retry_count++;
+ } else {
+ System.err.println(getName() +
+ " : out of retries. Giving up.");
+ retry = false;
+ }
+ } catch (DatabaseException e) {
+ // abort and don't retry
+ retry = false;
+ System.err.println(getName() +
+ " : caught exception: " + e.toString());
+ System.err.println(getName() +
+ " : errno: " + e.getErrno());
+ e.printStackTrace();
+ } finally {
+ if (txn != null) {
+ try {
+ txn.abort();
+ } catch (Exception e) {
+ System.err.println("Error aborting transaction: " +
+ e.toString());
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // This simply counts the number of objects contained in the
+ // store and returns the result. You can use this method
+ // in three ways:
+ //
+ // First call it with an active txn handle.
+ //
+ // Secondly, configure the cursor for dirty reads
+ //
+ // Third, call countObjects AFTER the writer has committed
+ // its transaction.
+ //
+ // If you do none of these things, the writer thread will
+ // self-deadlock.
+ private int countObjects(Transaction txn) throws DatabaseException {
+ int count = 0;
+
+ CursorConfig cc = new CursorConfig();
+ // This is ignored if the store is not opened with uncommitted read
+ // support.
+ cc.setReadUncommitted(true);
+ EntityCursor<PayloadDataEntity> cursor = pdKey.entities(txn, cc);
+
+ try {
+ for (PayloadDataEntity pdi : cursor) {
+ count++;
+ }
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+
+ return count;
+
+ }
+}
diff --git a/examples_java/src/persist/txn/TxnGuideDPL.java b/examples_java/src/persist/txn/TxnGuideDPL.java
new file mode 100644
index 0000000..d429507
--- /dev/null
+++ b/examples_java/src/persist/txn/TxnGuideDPL.java
@@ -0,0 +1,162 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2008-2009 Oracle. All rights reserved.
+ *
+ * $Id$
+ */
+
+// File TxnGuideDPL.java
+
+package persist.txn;
+
+import com.sleepycat.db.DatabaseConfig;
+import com.sleepycat.db.DatabaseException;
+import com.sleepycat.db.DatabaseType;
+import com.sleepycat.db.LockDetectMode;
+
+import com.sleepycat.db.Environment;
+import com.sleepycat.db.EnvironmentConfig;
+
+import com.sleepycat.persist.EntityStore;
+import com.sleepycat.persist.StoreConfig;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+public class TxnGuideDPL {
+
+ private static String myEnvPath = "./";
+ private static String storeName = "exampleStore";
+
+ // Handles
+ private static EntityStore myStore = null;
+ private static Environment myEnv = null;
+
+ private static final int NUMTHREADS = 5;
+
+ private static void usage() {
+ System.out.println("TxnGuideDPL [-h <env directory>]");
+ System.exit(-1);
+ }
+
+ public static void main(String args[]) {
+ try {
+ // Parse the arguments list
+ parseArgs(args);
+ // Open the environment and store
+ openEnv();
+
+ // Start the threads
+ StoreWriter[] threadArray;
+ threadArray = new StoreWriter[NUMTHREADS];
+ for (int i = 0; i < NUMTHREADS; i++) {
+ threadArray[i] = new StoreWriter(myEnv, myStore);
+ threadArray[i].start();
+ }
+
+ for (int i = 0; i < NUMTHREADS; i++) {
+ threadArray[i].join();
+ }
+ } catch (Exception e) {
+ System.err.println("TxnGuideDPL: " + e.toString());
+ e.printStackTrace();
+ } finally {
+ closeEnv();
+ }
+ System.out.println("All done.");
+ }
+
+
+ private static void openEnv() throws DatabaseException {
+ System.out.println("opening env and store");
+
+ // Set up the environment.
+ EnvironmentConfig myEnvConfig = new EnvironmentConfig();
+ myEnvConfig.setAllowCreate(true);
+ myEnvConfig.setInitializeCache(true);
+ myEnvConfig.setInitializeLocking(true);
+ myEnvConfig.setInitializeLogging(true);
+ myEnvConfig.setRunRecovery(true);
+ myEnvConfig.setTransactional(true);
+ // EnvironmentConfig.setThreaded(true) is the default behavior
+ // in Java, so we do not have to do anything to cause the
+ // environment handle to be free-threaded.
+
+ // Indicate that we want db to internally perform deadlock
+ // detection. Also indicate that the transaction that has
+ // performed the least amount of write activity to
+ // receive the deadlock notification, if any.
+ myEnvConfig.setLockDetectMode(LockDetectMode.MINWRITE);
+
+ // Set up the entity store
+ StoreConfig myStoreConfig = new StoreConfig();
+ myStoreConfig.setAllowCreate(true);
+ myStoreConfig.setTransactional(true);
+
+ // Need a DatabaseConfig object so as to set uncommitted read
+ // support.
+ DatabaseConfig myDbConfig = new DatabaseConfig();
+ myDbConfig.setType(DatabaseType.BTREE);
+ myDbConfig.setAllowCreate(true);
+ myDbConfig.setTransactional(true);
+ myDbConfig.setReadUncommitted(true);
+
+ try {
+ // Open the environment
+ myEnv = new Environment(new File(myEnvPath), // Env home
+ myEnvConfig);
+
+ // Open the store
+ myStore = new EntityStore(myEnv, storeName, myStoreConfig);
+
+ // Set the DatabaseConfig object, so that the underlying
+ // database is configured for uncommitted reads.
+ myStore.setPrimaryConfig(PayloadDataEntity.class, myDbConfig);
+ } catch (FileNotFoundException fnfe) {
+ System.err.println("openEnv: " + fnfe.toString());
+ System.exit(-1);
+ }
+ }
+
+ private static void closeEnv() {
+ System.out.println("Closing env and store");
+ if (myStore != null ) {
+ try {
+ myStore.close();
+ } catch (DatabaseException e) {
+ System.err.println("closeEnv: myStore: " +
+ e.toString());
+ e.printStackTrace();
+ }
+ }
+
+ if (myEnv != null ) {
+ try {
+ myEnv.close();
+ } catch (DatabaseException e) {
+ System.err.println("closeEnv: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private TxnGuideDPL() {}
+
+ private static void parseArgs(String args[]) {
+ int nArgs = args.length;
+ for(int i = 0; i < args.length; ++i) {
+ if (args[i].startsWith("-")) {
+ switch(args[i].charAt(1)) {
+ case 'h':
+ if (i < nArgs - 1) {
+ myEnvPath = new String(args[++i]);
+ }
+ break;
+ default:
+ usage();
+ }
+ }
+ }
+ }
+}