00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 package org.openmobileis.database.fastobjectdb.db.transaction;
00030
00031 import java.util.HashMap;
00032 import java.util.Iterator;
00033
00034 import org.openmobileis.common.util.PropertiesManager;
00035 import org.openmobileis.common.util.collection.Array;
00036 import org.openmobileis.database.fastobjectdb.db.exception.FODBException;
00037
00043 public final class TransactionManager {
00044 private HashMap transactionListbythread;
00045 private HashMap transactionFileListbyCollection;
00046 private HashMap collectionFileByThread;
00047 private boolean oneusermode = true;
00048 private Array threadToStop;
00052 public TransactionManager() {
00053 super();
00054 transactionListbythread = new HashMap(10);
00055 transactionFileListbyCollection = new HashMap(20);
00056 collectionFileByThread = new HashMap(10);
00057 threadToStop = new Array();
00058 String oneuser = PropertiesManager.getManager().getProperty("org.openmobileis.database.fastobjectdb.usermode");
00059 if ((oneuser !=null) && (oneuser.equals("false"))) {
00060 oneusermode = false;
00061 }
00062 }
00063
00064 private Transaction getTransaction() {
00065 Thread th = Thread.currentThread();
00066 Transaction ret = (Transaction)transactionListbythread.get(th);
00067 if (ret==null) {
00068 ret = new Transaction(th);
00069 transactionListbythread.put(th, ret);
00070 }
00071 return ret;
00072 }
00073
00074 public synchronized void registerTransactionFile(TransactionFile file, String collectionName) {
00075 transactionFileListbyCollection.put(collectionName, file);
00076 }
00077
00078 public void validateThread(Thread th) throws FODBException {
00079 if (oneusermode) {
00080 synchronized(threadToStop) {
00081 if (threadToStop.size()>0) {
00082 if (threadToStop.contains(th)) {
00083 throw new FODBException("Thread stopped by other thread. One User mode.");
00084 }
00085 }
00086 }
00087 }
00088 }
00089
00090 public synchronized void enterTransaction(String collectionName) throws FODBException {
00091
00092 try {
00093 Thread th = Thread.currentThread();
00094 Transaction othertr = null;
00095 synchronized (collectionFileByThread) {
00096 othertr = (Transaction)collectionFileByThread.get(collectionName);
00097 }
00098 if ((othertr != null) && (!othertr.getTransactionThread().equals(th))) {
00099 if (oneusermode) {
00100 synchronized(threadToStop) {
00101 threadToStop.add(othertr.getTransactionThread());
00102 }
00103 }
00104 synchronized(th) {
00105 othertr.pushThread(th);
00106 th.wait();
00107 }
00108 }
00109
00110 TransactionFile file = (TransactionFile)transactionFileListbyCollection.get(collectionName);
00111 if (file != null) {
00112 Transaction tr = this.getTransaction();
00113 tr.addTransactionFile(file);
00114 synchronized (collectionFileByThread) {
00115 collectionFileByThread.put(collectionName, tr);
00116 }
00117 } else {
00118 throw new FODBException("ERROR TransactionManager Unregistered Collection :"+collectionName+" try to enter transaction.");
00119 }
00120 } catch (Throwable ex){
00121 throw new FODBException(ex);
00122 }
00123 }
00124
00125 public void begin() throws FODBException {
00126
00127 this.getTransaction().begin();
00128 }
00129
00130 public void commit() throws FODBException {
00131
00132 Transaction tr = this.getTransaction();
00133 boolean effective = tr.commit();
00134 if (effective) {
00135 this.processEndTransaction(tr);
00136 }
00137 }
00138
00139 private void processEndTransaction(Transaction tr) {
00140 transactionListbythread.remove(Thread.currentThread());
00141 if (oneusermode) {
00142 synchronized(threadToStop) {
00143 if (threadToStop.size()>0) {
00144 threadToStop.remove(tr.getTransactionThread());
00145 }
00146 }
00147 }
00148
00149 synchronized (collectionFileByThread) {
00150 Iterator iter = collectionFileByThread.keySet().iterator();
00151 Array keylist = new Array();
00152 while (iter.hasNext()) {
00153 Object key = iter.next();
00154 Object maptr = collectionFileByThread.get(key);
00155 if (maptr.equals(tr)) keylist.add(key);
00156 }
00157 for (int i=0; i<keylist.size(); i++) {
00158 collectionFileByThread.remove(keylist.get(i));
00159 }
00160 }
00161 tr.popallthread();
00162 }
00163
00164 public void rollback() throws FODBException {
00165
00166 Transaction tr = this.getTransaction();
00167 boolean effective = tr.rollback();
00168 if (effective) {
00169 this.processEndTransaction(tr);
00170 }
00171 }
00172
00173 }