1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.com *
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. *
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. *
15 ***************************************************************************/
16 #include<Transaction.h>
20 #include<CatalogTables.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
++;
35 undoLogCount
+= iter
->noOfUndoLogs();
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
++;
61 undoLogCount
+= iter
->noOfUndoLogs();
62 iter
->printDebugInfo(sysdb
);
67 printf(" <UsedSlots> %d </UsedSlots>\n", usedCount
);
68 printf(" <FreeSlots> %d </FreeSlots>\n", freeCount
);
70 printf(" <UndoLogs>\n");
71 printf(" <TotalNodes> %d </TotalNodes>\n", undoLogCount
);
72 printf(" </UndoLogs>\n");
73 printf("</TransactionTable>\n");
77 DbRetVal
TransactionManager::startTransaction(LockManager
*lMgr
, IsolationLevel level
)
79 Database
*sysdb
= lMgr
->systemDatabase_
;
80 Transaction
*trans
= ProcessManager::getThreadTransaction(sysdb
->procSlot
);
83 if (trans
->status_
!= TransNotUsed
) return ErrAlready
;
85 //the previous transaction shall be used again
86 trans
->status_
= TransRunning
;
87 trans
->isoLevel_
= level
;
88 printDebug(DM_Transaction
, "Using the same transaction slot\n");
94 DbRetVal rv
= sysdb
->getTransTableMutex();
97 printError(ErrSysInternal
, "Unable to acquire transtable mutex");
98 return ErrSysInternal
;
100 Transaction
*iter
= firstTrans
;
102 for (i
=0 ; i
< Conf::config
.getMaxProcs(); i
++)
104 if (iter
->status_
== TransNotUsed
) break;
107 // if Transaction table is full return error
108 if (i
== Conf::config
.getMaxProcs()) {
109 printError(ErrNoResource
, "Transaction slots are full");
110 sysdb
->releaseTransTableMutex();
111 return ErrNoResource
;
113 printDebug(DM_Transaction
, "Using transaction slot %d \n", i
);
115 //Make this free slot, as the current transaction and
118 trans
->status_
= TransRunning
;
119 trans
->isoLevel_
= level
;
120 sysdb
->releaseTransTableMutex();
121 ProcessManager::setThreadTransaction(trans
, sysdb
->procSlot
);
125 void TransactionManager::setFirstTrans(Transaction
*trans
)
131 DbRetVal
TransactionManager::commit(LockManager
*lockManager
)
133 Database
*sysdb
= lockManager
->systemDatabase_
;
134 Transaction
*trans
= ProcessManager::getThreadTransaction(sysdb
->procSlot
);
137 printError(ErrNotOpen
, "No transaction started for this procSlot %d", sysdb
->procSlot
);
140 DbRetVal rv
= sysdb
->getTransTableMutex();
143 printError(ErrSysInternal
, "Unable to acquire transtable mutex");
144 return ErrSysInternal
;
147 if (trans
->status_
!= TransRunning
)
149 sysdb
->releaseTransTableMutex();
150 printError(ErrBadCall
, "Transaction is not in running state\n");
153 trans
->status_
= TransCommitting
;
154 sysdb
->releaseTransTableMutex();
156 trans
->releaseAllLocks(lockManager
);
157 if(NULL
!= trans
->waitLock_
)
159 printError(ErrSysInternal
, "Trans WaitLock is not null\n");
160 return ErrSysInternal
;
162 //TODO::flush all redo logs to disk
163 //TODO::remove all the logs in memory
164 trans
->removeUndoLogs(sysdb
);
165 rv
= sysdb
->getTransTableMutex();
168 printError(ErrSysInternal
, "Unable to acquire transtable mutex");
169 return ErrSysInternal
;
171 trans
->status_
= TransNotUsed
;
172 sysdb
->releaseTransTableMutex();
173 printDebug(DM_Transaction
, "Committed transaction:%x",trans
);
177 DbRetVal
TransactionManager::rollback(LockManager
*lockManager
, Transaction
*t
)
179 Database
*sysdb
= lockManager
->systemDatabase_
;
182 trans
= ProcessManager::getThreadTransaction(sysdb
->procSlot
);
189 DbRetVal rv
= sysdb
->getTransTableMutex();
192 printError(ErrSysInternal
, "Unable to acquire transtable mutex");
193 return ErrSysInternal
;
196 if (trans
->status_
!= TransRunning
)
198 sysdb
->releaseTransTableMutex();
199 //will be called during connection disconnect without starting transaction.
202 trans
->status_
= TransAborting
;
203 sysdb
->releaseTransTableMutex();
205 trans
->applyUndoLogs(sysdb
);
206 //TODO::remove all the logs in memory
207 trans
->releaseAllLocks(lockManager
);
208 if(NULL
!= trans
->waitLock_
)
210 printError(ErrSysInternal
, "Trans waitlock is not null");
211 return ErrSysInternal
;
214 sysdb
->getTransTableMutex();
215 trans
->status_
= TransNotUsed
;
216 sysdb
->releaseTransTableMutex();
217 printDebug(DM_Transaction
, "Aborted transaction:%x",trans
);