1
0
Fork 0

Revised cache transaction handling.

Use a RAII object to manage cache transactions, and reset queries immediately after they are done, to avoid auto-commit transactions lasting long periods of time. Re-write the commit and step logic to handle SQLITE_BUSY, with progressively increasing waits when there is DB contention (multiple processes accessing the DB).
This commit is contained in:
James Turner 2012-12-23 23:32:53 +00:00
parent 3c6fbffdf2
commit 41481967f1
5 changed files with 269 additions and 156 deletions

View file

@ -43,7 +43,10 @@ double FGTaxiNode::getElevationFt()
SGGeod newPos = mPosition;
newPos.setElevationM(elevationEnd);
// this will call modifyPosition to update mPosition
NavDataCache::instance()->updatePosition(guid(), newPos);
NavDataCache* cache = NavDataCache::instance();
NavDataCache::Transaction txn(cache);
cache->updatePosition(guid(), newPos);
txn.commit();
}
}

View file

@ -396,17 +396,12 @@ void FGAirport::loadSceneryDefinitions() const
return;
}
try {
cache->beginTransaction();
flightgear::NavDataCache::Transaction txn(cache);
SGPropertyNode_ptr rootNode = new SGPropertyNode;
readProperties(path.str(), rootNode);
const_cast<FGAirport*>(this)->readThresholdData(rootNode);
cache->stampCacheFile(path);
cache->commitTransaction();
} catch (sg_exception& e) {
cache->abortTransaction();
throw e;
}
txn.commit();
}
void FGAirport::readThresholdData(SGPropertyNode* aRoot)
@ -480,11 +475,13 @@ void FGAirport::validateTowerData() const
// cached values are correct, we're all done
return;
}
flightgear::NavDataCache::Transaction txn(cache);
SGPropertyNode_ptr rootNode = new SGPropertyNode;
readProperties(path.str(), rootNode);
const_cast<FGAirport*>(this)->readTowerData(rootNode);
cache->stampCacheFile(path);
txn.commit();
}
void FGAirport::readTowerData(SGPropertyNode* aRoot)
@ -529,9 +526,12 @@ bool FGAirport::validateILSData()
SGPropertyNode_ptr rootNode = new SGPropertyNode;
readProperties(path.str(), rootNode);
flightgear::NavDataCache::Transaction txn(cache);
readILSData(rootNode);
cache->stampCacheFile(path);
txn.commit();
// we loaded data, tell the caller it might need to reload things
return true;
}

View file

@ -55,7 +55,7 @@ void XMLLoader::load(FGAirportDynamics* d)
SG_LOG(SG_NAVAID, SG_INFO, "reading groundnet data from " << path);
SGTimeStamp t;
try {
cache->beginTransaction();
flightgear::NavDataCache::Transaction txn(cache);
t.stamp();
{
// drop all current data
@ -65,9 +65,9 @@ void XMLLoader::load(FGAirportDynamics* d)
readXML(path.str(), visitor);
} // ensure visitor is destroyed so its destructor runs
cache->stampCacheFile(path);
cache->commitTransaction();
txn.commit();
} catch (sg_exception& e) {
cache->abortTransaction();
SG_LOG(SG_NAVAID, SG_INFO, "parsing groundnet XML failed:" << e.getFormattedMessage());
}
SG_LOG(SG_NAVAID, SG_INFO, "parsing groundnet XML took " << t.elapsedMSec());

File diff suppressed because it is too large Load diff

View file

@ -85,11 +85,6 @@ public:
string_list readStringListProperty(const std::string& key);
void writeStringListProperty(const std::string& key, const string_list& values);
// transaction API wrappers
void beginTransaction();
void commitTransaction();
void abortTransaction();
/**
* retrieve an FGPositioned from the cache.
* This may be trivial if the object is previously loaded, or require actual
@ -250,12 +245,31 @@ public:
PositionedIDVec findAirportParking(PositionedID airport, const std::string& flightType,
int radius);
class Transaction
{
public:
Transaction(NavDataCache* cache);
~Transaction();
void commit();
private:
NavDataCache* _instance;
bool _committed;
};
private:
NavDataCache();
friend class RebuildThread;
void doRebuild();
friend class Transaction;
void beginTransaction();
void commitTransaction();
void abortTransaction();
class NavDataCachePrivate;
std::auto_ptr<NavDataCachePrivate> d;
};