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 #include "eyedb_p.h"
00026 #include "DBM_Database.h"
00027 #include "IteratorBE.h"
00028 #include "OQLBE.h"
00029 #include "BEQueue.h"
00030 #include "kernel.h"
00031 #include "db_p.h"
00032
00033 namespace eyedb {
00034
00035 static const int defMagOrder = 10240;
00036
00037 Transaction::Transaction(Database *_db,
00038 const TransactionParams &_params) :
00039 db(_db), params(_params), incoherency(False)
00040 {
00041 cacheInit();
00042 cache_on = True;
00043 }
00044
00045 void
00046 Transaction::cacheInit()
00047 {
00048 int n = (params.magorder >= defMagOrder ? params.magorder : defMagOrder) / 20;
00049 int p = 1;
00050
00051 for (;;)
00052 {
00053 if (p >= n)
00054 break;
00055 p <<= 1;
00056 }
00057
00058 cache = new ObjCache(p);
00059 }
00060
00061 Status Transaction::setParams(const TransactionParams &_params)
00062 {
00063 Status s;
00064
00065 if (s = checkParams(_params))
00066 return s;
00067
00068 params = _params;
00069
00070 RPCStatus rpc_status;
00071 if ((rpc_status = transactionParamsSet(db->getDbHandle(), ¶ms)) !=
00072 RPCSuccess)
00073 return StatusMake(rpc_status);
00074
00075 return Success;
00076 }
00077
00078 Status Transaction::begin()
00079 {
00080 RPCStatus rpc_status;
00081
00082 if ((rpc_status = transactionBegin(db->getDbHandle(),
00083 ¶ms,
00084 &tid)) != RPCSuccess)
00085 return StatusMake(rpc_status);
00086
00087 return Success;
00088 }
00089
00090 Status Transaction::commit()
00091 {
00092 RPCStatus rpc_status;
00093
00094 if (incoherency)
00095 {
00096
00097
00098 return Exception::make(IDB_ERROR, "current transaction could not "
00099 "committed because of an incoherency state: "
00100 "must abort current transaction.");
00101 }
00102
00103
00104
00105 if ((rpc_status = transactionCommit(db->getDbHandle(), tid)) != RPCSuccess)
00106 return StatusMake(rpc_status);
00107
00108 return Success;
00109 }
00110
00111 Status Transaction::abort()
00112 {
00113 RPCStatus rpc_status;
00114
00115 if ((rpc_status = transactionAbort(db->getDbHandle(), tid)) != RPCSuccess)
00116 return StatusMake(rpc_status);
00117
00118 incoherency = False;
00119 if (db->getSchema()->isModify())
00120 {
00121 begin();
00122 db->getSchema()->purge();
00123 commit();
00124 }
00125
00126 return Success;
00127 }
00128
00129 Status Transaction::checkParams(const TransactionParams ¶ms,
00130 Bool strict)
00131 {
00132 if (params.trsmode != TransactionOff &&
00133 params.trsmode != TransactionOn)
00134 return Exception::make(IDB_INVALID_TRANSACTION_PARAMS,
00135 "invalid transaction mode %d", params.trsmode);
00136
00137 if (params.lockmode != ReadSWriteS &&
00138 params.lockmode != ReadSWriteSX &&
00139 params.lockmode != ReadSWriteX &&
00140 params.lockmode != ReadSXWriteSX &&
00141 params.lockmode != ReadSXWriteX &&
00142 params.lockmode != ReadXWriteX &&
00143 params.lockmode != ReadNWriteS &&
00144 params.lockmode != ReadNWriteSX &&
00145 params.lockmode != ReadNWriteX &&
00146 params.lockmode != ReadNWriteN &&
00147 params.lockmode != DatabaseW &&
00148 params.lockmode != DatabaseRW &&
00149 params.lockmode != DatabaseWtrans)
00150 return Exception::make(IDB_INVALID_TRANSACTION_PARAMS,
00151 "invalid lock mode %d", params.lockmode);
00152
00153 if (params.recovmode != RecoveryOff &&
00154 params.recovmode != RecoveryFull &&
00155 params.recovmode != RecoveryPartial)
00156 return Exception::make(IDB_INVALID_TRANSACTION_PARAMS,
00157 "invalid recovery mode %d", params.recovmode);
00158 return Success;
00159 }
00160
00161 void Transaction::cacheObject(const Oid &oid, Object *o)
00162 {
00163 if (cache_on && o && o->getOid().isValid())
00164 cache->insertObject(oid, o);
00165 }
00166
00167 void Transaction::uncacheObject(Object *o)
00168 {
00169 if (o && o->getOid().isValid())
00170 cache->deleteObject(o->getOid());
00171 }
00172
00173 void Transaction::uncacheObject(const Oid &_oid)
00174 {
00175 cache->deleteObject(_oid);
00176 }
00177
00178 Status
00179 Transaction::cacheInvalidate()
00180 {
00181 delete cache;
00182 cacheInit();
00183 return Success;
00184 }
00185
00186 Status
00187 Transaction::setCacheActive(Bool on_off)
00188 {
00189 cache_on = on_off;
00190 return Success;
00191 }
00192
00193 void
00194 Transaction::setIncoherency()
00195 {
00196 incoherency = True;
00197 }
00198
00199 Transaction::~Transaction()
00200 {
00201 delete cache;
00202 }
00203 }