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:
parent
3c6fbffdf2
commit
41481967f1
5 changed files with 269 additions and 156 deletions
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue