00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 package com.sleepycat.collections;
00011
00012 import com.sleepycat.compat.DbCompat;
00013 import com.sleepycat.db.DatabaseException;
00014 import com.sleepycat.db.DeadlockException;
00015 import com.sleepycat.db.Environment;
00016 import com.sleepycat.db.Transaction;
00017 import com.sleepycat.db.TransactionConfig;
00018 import com.sleepycat.util.ExceptionUnwrapper;
00019
00075 public class TransactionRunner {
00076
00078 public static final int DEFAULT_MAX_RETRIES = 10;
00079
00080 private Environment env;
00081 private CurrentTransaction currentTxn;
00082 private int maxRetries;
00083 private TransactionConfig config;
00084 private boolean allowNestedTxn;
00085
00093 public TransactionRunner(Environment env) {
00094
00095 this(env, DEFAULT_MAX_RETRIES, null);
00096 }
00097
00112 public TransactionRunner(Environment env, int maxRetries,
00113 TransactionConfig config) {
00114
00115 this.env = env;
00116 this.currentTxn = CurrentTransaction.getInstance(env);
00117 this.maxRetries = maxRetries;
00118 this.config = config;
00119 }
00120
00125 public int getMaxRetries() {
00126
00127 return maxRetries;
00128 }
00129
00135 public void setMaxRetries(int maxRetries) {
00136
00137 this.maxRetries = maxRetries;
00138 }
00139
00149 public boolean getAllowNestedTransactions() {
00150
00151 return allowNestedTxn;
00152 }
00153
00163 public void setAllowNestedTransactions(boolean allowNestedTxn) {
00164
00165 if (allowNestedTxn && !DbCompat.NESTED_TRANSACTIONS) {
00166 throw new UnsupportedOperationException(
00167 "Nested transactions are not supported.");
00168 }
00169 this.allowNestedTxn = allowNestedTxn;
00170 }
00171
00182 public TransactionConfig getTransactionConfig() {
00183
00184 return config;
00185 }
00186
00197 public void setTransactionConfig(TransactionConfig config) {
00198
00199 this.config = config;
00200 }
00201
00218 public void run(TransactionWorker worker)
00219 throws DatabaseException, Exception {
00220
00221 if (currentTxn != null &&
00222 (allowNestedTxn || currentTxn.getTransaction() == null)) {
00223
00224
00225
00226
00227 for (int i = 0;; i += 1) {
00228 Transaction txn = null;
00229 try {
00230 txn = currentTxn.beginTransaction(config);
00231 worker.doWork();
00232 if (txn != null && txn == currentTxn.getTransaction()) {
00233 currentTxn.commitTransaction();
00234 }
00235 return;
00236 } catch (Throwable e) {
00237 e = ExceptionUnwrapper.unwrapAny(e);
00238 if (txn != null && txn == currentTxn.getTransaction()) {
00239 try {
00240 currentTxn.abortTransaction();
00241 } catch (Throwable e2) {
00242
00243
00244
00245
00246
00247
00248 e2.printStackTrace();
00249
00250 i = maxRetries + 1;
00251 }
00252 }
00253 if (i >= maxRetries || !(e instanceof DeadlockException)) {
00254 if (e instanceof Exception) {
00255 throw (Exception) e;
00256 } else {
00257 throw (Error) e;
00258 }
00259 }
00260 }
00261 }
00262 } else {
00263
00264
00265
00266
00267 try {
00268 worker.doWork();
00269 } catch (Exception e) {
00270 throw ExceptionUnwrapper.unwrap(e);
00271 }
00272 }
00273 }
00274 }