code reorg
[csql.git] / src / server / TransactionManager.cxx
blobdd8415a7d5569732c44164ff715c6e4d1c5d7626
1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 ***************************************************************************/
16 #include<Transaction.h>
17 #include<Lock.h>
18 #include<Database.h>
19 #include<Allocator.h>
20 #include<CatalogTables.h>
21 #include<Debug.h>
22 #include<Config.h>
23 #include<Process.h>
25 void TransactionManager::printUsageStatistics()
27 Transaction *iter = firstTrans;
28 int i=0, usedCount =0, freeCount =0, undoLogCount=0;
29 for (; i < Conf::config.getMaxProcs(); i++)
31 if (iter->status_ == TransNotUsed) freeCount++;
32 else
34 usedCount++;
35 undoLogCount += iter->noOfUndoLogs();
37 iter++;
39 printf("<TransactionTable>\n");
40 printf(" <UsedSlots> %d </UsedSlots>\n", usedCount);
41 printf(" <FreeSlots> %d </FreeSlots>\n", freeCount);
43 printf(" <UndoLogs>\n");
44 printf(" <TotalNodes> %d </TotalNodes>\n", undoLogCount);
45 printf(" </UndoLogs>\n");
46 printf("</TransactionTable>\n");
50 void TransactionManager::printDebugInfo(Database *sysdb)
52 Transaction *iter = firstTrans;
53 int i=0, usedCount =0, freeCount =0, undoLogCount=0;
54 printf("<TransactionTable>\n");
55 for (; i < Conf::config.getMaxProcs(); i++)
57 if (iter->status_ == TransNotUsed) freeCount++;
58 else
60 usedCount++;
61 undoLogCount += iter->noOfUndoLogs();
62 iter->printDebugInfo(sysdb);
64 iter++;
67 printf(" <UsedSlots> %d </UsedSlots>\n", usedCount);
68 printf(" <FreeSlots> %d </FreeSlots>\n", freeCount);
70 Chunk *chunk = sysdb->getSystemDatabaseChunk(UndoLogTableID);
72 printf(" <UndoLogs>\n");
73 printf(" <TotalNodes> %d </TotalNodes>\n", undoLogCount);
74 printf(" <TotalPages> %d </TotalPages>\n", chunk->totalPages());
75 printf(" </UndoLogs>\n");
76 printf("</TransactionTable>\n");
80 DbRetVal TransactionManager::startTransaction(LockManager *lMgr, IsolationLevel level)
82 Database *sysdb = lMgr->systemDatabase_;
83 Transaction *trans = ProcessManager::getThreadTransaction(sysdb->procSlot);
84 if (NULL != trans)
86 if (trans->status_ != TransNotUsed) return ErrAlready;
87 else {
88 //the previous transaction shall be used again
89 trans->status_ = TransRunning;
90 trans->isoLevel_ = level;
91 printDebug(DM_Transaction, "Using the same transaction slot\n");
92 return OK;
97 DbRetVal rv = sysdb->getTransTableMutex();
98 if (OK != rv)
100 printError(rv, "Unable to acquire transtable mutex");
101 return rv;
103 Transaction *iter = firstTrans;
104 int i;
105 for (i =0 ; i < Conf::config.getMaxProcs(); i++)
107 if (iter->status_ == TransNotUsed) break;
108 iter++;
110 // if Transaction table is full return error
111 if (i == Conf::config.getMaxProcs()) {
112 printError(ErrNoResource, "Transaction slots are full");
113 sysdb->releaseTransTableMutex();
114 return ErrNoResource;
116 printDebug(DM_Transaction, "Using transaction slot %d \n", i);
118 //Make this free slot, as the current transaction and
119 //set the state
120 trans = iter;
121 trans->status_ = TransRunning;
122 trans->isoLevel_ = level;
123 sysdb->releaseTransTableMutex();
124 ProcessManager::setThreadTransaction(trans, sysdb->procSlot);
125 return OK;
128 void TransactionManager::setFirstTrans(Transaction *trans)
130 firstTrans = trans;
134 DbRetVal TransactionManager::commit(LockManager *lockManager)
136 Database *sysdb = lockManager->systemDatabase_;
137 Transaction *trans = ProcessManager::getThreadTransaction(sysdb->procSlot);
138 if (NULL == trans)
140 printError(ErrNotOpen, "No transaction started for this procSlot %d", sysdb->procSlot);
141 return ErrNotOpen;
143 DbRetVal rv = sysdb->getTransTableMutex();
144 if (OK != rv)
146 printError(rv, "Unable to acquire transtable mutex");
147 return rv;
150 if (trans->status_ != TransRunning)
152 sysdb->releaseTransTableMutex();
153 printError(ErrBadCall, "Transaction is not in running state %d\n", trans->status_);
154 return ErrBadCall;
156 trans->status_ = TransCommitting;
157 sysdb->releaseTransTableMutex();
159 trans->releaseAllLocks(lockManager);
160 if(NULL != trans->waitLock_)
162 printError(ErrSysInternal, "Trans WaitLock is not null\n");
163 return ErrSysInternal;
165 //TODO::flush all redo logs to disk
166 //TODO::remove all the logs in memory
167 trans->removeUndoLogs(sysdb);
168 rv = sysdb->getTransTableMutex();
169 if (OK != rv)
171 printError(rv, "Unable to acquire transtable mutex");
172 return rv;
174 trans->status_ = TransNotUsed;
175 sysdb->releaseTransTableMutex();
176 printDebug(DM_Transaction, "Committed transaction:%x",trans);
177 return OK;
180 DbRetVal TransactionManager::rollback(LockManager *lockManager, Transaction *t)
182 Database *sysdb = lockManager->systemDatabase_;
183 Transaction *trans;
184 if (t == NULL)
185 trans = ProcessManager::getThreadTransaction(sysdb->procSlot);
186 else
187 trans = t;
188 if (NULL == trans)
190 return OK;
192 DbRetVal rv= sysdb->getTransTableMutex();
193 if (OK != rv)
195 printError(rv, "Unable to acquire transtable mutex");
196 return rv;
199 if (trans->status_ != TransRunning)
201 sysdb->releaseTransTableMutex();
202 //will be called during connection disconnect without starting transaction.
203 return OK;
205 trans->status_ = TransAborting;
206 sysdb->releaseTransTableMutex();
208 trans->applyUndoLogs(sysdb);
209 //TODO::remove all the logs in memory
210 trans->releaseAllLocks(lockManager);
211 if(NULL != trans->waitLock_)
213 printError(ErrSysInternal, "Trans waitlock is not null");
214 return ErrSysInternal;
217 rv = sysdb->getTransTableMutex();
218 if (OK != rv)
220 //nothing can be done.. go ahead and set it.
221 //no harm. parallel starttransaction will miss this slot. thats ok
222 //as it is not leak
224 trans->status_ = TransNotUsed;
225 sysdb->releaseTransTableMutex();
226 printDebug(DM_Transaction, "Aborted transaction:%x",trans);
228 return OK;