00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include<Transaction.h>
00017 #include<Lock.h>
00018 #include<Database.h>
00019 #include<Allocator.h>
00020 #include<CatalogTables.h>
00021 #include<Debug.h>
00022 #include<Config.h>
00023 #include<Process.h>
00024
00025 void TransactionManager::printUsageStatistics()
00026 {
00027 Transaction *iter = firstTrans;
00028 int i=0, usedCount =0, freeCount =0, undoLogCount=0;
00029 for (; i < Conf::config.getMaxProcs(); i++)
00030 {
00031 if (iter->status_ == TransNotUsed) freeCount++;
00032 else
00033 {
00034 usedCount++;
00035 undoLogCount += iter->noOfUndoLogs();
00036 }
00037 iter++;
00038 }
00039 printf("<TransactionTable>\n");
00040 printf(" <UsedSlots> %d </UsedSlots>\n", usedCount);
00041 printf(" <FreeSlots> %d </FreeSlots>\n", freeCount);
00042
00043 printf(" <UndoLogs>\n");
00044 printf(" <TotalNodes> %d </TotalNodes>\n", undoLogCount);
00045 printf(" </UndoLogs>\n");
00046 printf("</TransactionTable>\n");
00047
00048 }
00049
00050 void TransactionManager::printDebugInfo(Database *sysdb)
00051 {
00052 Transaction *iter = firstTrans;
00053 int i=0, usedCount =0, freeCount =0, undoLogCount=0;
00054 printf("<TransactionTable>\n");
00055 for (; i < Conf::config.getMaxProcs(); i++)
00056 {
00057 if (iter->status_ == TransNotUsed) freeCount++;
00058 else
00059 {
00060 usedCount++;
00061 undoLogCount += iter->noOfUndoLogs();
00062 iter->printDebugInfo(sysdb);
00063 }
00064 iter++;
00065 }
00066
00067 printf(" <UsedSlots> %d </UsedSlots>\n", usedCount);
00068 printf(" <FreeSlots> %d </FreeSlots>\n", freeCount);
00069
00070 Chunk *chunk = sysdb->getSystemDatabaseChunk(UndoLogTableID);
00071
00072 printf(" <UndoLogs>\n");
00073 printf(" <TotalNodes> %d </TotalNodes>\n", undoLogCount);
00074 printf(" <TotalPages> %d </TotalPages>\n", chunk->totalPages());
00075 printf(" </UndoLogs>\n");
00076 printf("</TransactionTable>\n");
00077 }
00078
00079
00080 DbRetVal TransactionManager::startTransaction(LockManager *lMgr, IsolationLevel level)
00081 {
00082 Database *sysdb = lMgr->systemDatabase_;
00083 Transaction *trans = ProcessManager::getThreadTransaction(sysdb->procSlot);
00084 if (NULL != trans)
00085 {
00086 if (trans->status_ != TransNotUsed) return ErrAlready;
00087 else {
00088
00089 trans->status_ = TransRunning;
00090 trans->isoLevel_ = level;
00091 printDebug(DM_Transaction, "Using the same transaction slot\n");
00092 return OK;
00093 }
00094
00095 }
00096
00097 DbRetVal rv = sysdb->getTransTableMutex();
00098 if (OK != rv)
00099 {
00100 printError(rv, "Unable to acquire transtable mutex");
00101 return rv;
00102 }
00103 Transaction *iter = firstTrans;
00104 int i;
00105 for (i =0 ; i < Conf::config.getMaxProcs(); i++)
00106 {
00107 if (iter->status_ == TransNotUsed) break;
00108 iter++;
00109 }
00110
00111 if (i == Conf::config.getMaxProcs()) {
00112 printError(ErrNoResource, "Transaction slots are full");
00113 sysdb->releaseTransTableMutex();
00114 return ErrNoResource;
00115 }
00116 printDebug(DM_Transaction, "Using transaction slot %d \n", i);
00117
00118
00119
00120 trans = iter;
00121 trans->status_ = TransRunning;
00122 trans->isoLevel_ = level;
00123 sysdb->releaseTransTableMutex();
00124 ProcessManager::setThreadTransaction(trans, sysdb->procSlot);
00125 return OK;
00126 }
00127
00128 void TransactionManager::setFirstTrans(Transaction *trans)
00129 {
00130 firstTrans = trans;
00131 }
00132
00133
00134 DbRetVal TransactionManager::commit(LockManager *lockManager)
00135 {
00136 Database *sysdb = lockManager->systemDatabase_;
00137 Transaction *trans = ProcessManager::getThreadTransaction(sysdb->procSlot);
00138 if (NULL == trans)
00139 {
00140 printError(ErrNotOpen, "No transaction started for this procSlot %d", sysdb->procSlot);
00141 return ErrNotOpen;
00142 }
00143 DbRetVal rv = sysdb->getTransTableMutex();
00144 if (OK != rv)
00145 {
00146 printError(rv, "Unable to acquire transtable mutex");
00147 return rv;
00148 }
00149
00150 if (trans->status_ != TransRunning)
00151 {
00152 sysdb->releaseTransTableMutex();
00153 printError(ErrBadCall, "Transaction is not in running state %d\n", trans->status_);
00154 return ErrBadCall;
00155 }
00156 trans->status_ = TransCommitting;
00157 sysdb->releaseTransTableMutex();
00158
00159 trans->releaseAllLocks(lockManager);
00160 if(NULL != trans->waitLock_)
00161 {
00162 printError(ErrSysInternal, "Trans WaitLock is not null\n");
00163 return ErrSysInternal;
00164 }
00165
00166
00167 trans->removeUndoLogs(sysdb);
00168 rv = sysdb->getTransTableMutex();
00169 if (OK != rv)
00170 {
00171 printError(rv, "Unable to acquire transtable mutex");
00172 return rv;
00173 }
00174 trans->status_ = TransNotUsed;
00175 sysdb->releaseTransTableMutex();
00176 printDebug(DM_Transaction, "Committed transaction:%x",trans);
00177 return OK;
00178 }
00179
00180 DbRetVal TransactionManager::rollback(LockManager *lockManager, Transaction *t)
00181 {
00182 Database *sysdb = lockManager->systemDatabase_;
00183 Transaction *trans;
00184 if (t == NULL)
00185 trans = ProcessManager::getThreadTransaction(sysdb->procSlot);
00186 else
00187 trans = t;
00188 if (NULL == trans)
00189 {
00190 return OK;
00191 }
00192 DbRetVal rv= sysdb->getTransTableMutex();
00193 if (OK != rv)
00194 {
00195 printError(rv, "Unable to acquire transtable mutex");
00196 return rv;
00197 }
00198
00199 if (trans->status_ != TransRunning)
00200 {
00201 sysdb->releaseTransTableMutex();
00202
00203 return OK;
00204 }
00205 trans->status_ = TransAborting;
00206 sysdb->releaseTransTableMutex();
00207
00208 trans->applyUndoLogs(sysdb);
00209
00210 trans->releaseAllLocks(lockManager);
00211 if(NULL != trans->waitLock_)
00212 {
00213 printError(ErrSysInternal, "Trans waitlock is not null");
00214 return ErrSysInternal;
00215 }
00216
00217 rv = sysdb->getTransTableMutex();
00218 if (OK != rv)
00219 {
00220
00221
00222
00223 }
00224 trans->status_ = TransNotUsed;
00225 sysdb->releaseTransTableMutex();
00226 printDebug(DM_Transaction, "Aborted transaction:%x",trans);
00227
00228 return OK;
00229 }