die folgende Implementierung einer generischen Funktion Angenommen, eine Datenbank zur Abfrage MySQL:Ist dies eine sichere Implementierung einer generischen SQL-Ausführungsfunktion?
bool execute(const sql::SQLString query, std::vector<sql::ResultSet*> &results)
{
// ConnectionPool holds premade connections to the database
sql::Connection* conn = ConnectionPool::getInstance()::getConnection();
std::unique_ptr<sql::Statement> stmt;
bool success = false;
try
{
stmt.reset(conn->createStatement());
stmt->execute(query);
do
{
results.push_back(stmt->getResultSet());
} while (stmt->getMoreResults())
success = true;
}
catch (...)
{
// Other catch() statements are not a part of this question
std::cerr << "Exception caught!" << std::endl;
success = false;
}
conn->commit();
ConnectionPool::getInstance()::returnConnection(conn);
return success;
}
Nach this example für die Ergebnisse einer Abfrage abzurufen, muss die ResultSet explizit gelöscht werden. In Bezug auf die obige Implementierung bedeutet dies, dass der Vektor von ResultSet-Zeigern sicher zu verwenden ist (d. H. Die Objekte, auf die sie zeigen, werden durch das Löschen der Erstellanweisung nicht gelöscht)?
Auch mache ich irgendetwas Unaussprechliches Böses mit dieser Implementierung?
Sollten Sie eine Festschreibung vornehmen, wenn eine Ausnahme aufgetreten ist? Solltest du versuchen, deinen Verbindungs-Commit zu umgehen? In jedem Fall muss dies dokumentiert werden. Im Beispiel löschen sie das Ergebnis vor dem stmt; abhängig davon, wie verrückt ihre Ressourcenverwaltung ist ... Wenn die Ergebnismenge gelöscht werden soll, sollte auch ein Vektor eindeutiger Zeiger auf sie verwaltet werden, nicht rohe Zeiger. Die Lebensdauer von stmt ist länger als die Lebensdauer der Verbindung, ist das ein Problem? – Yakk
@Yakk Unser Modell ist immer die Verbindung zu machen; entweder am Ende der Funktion oder in try() und catch(). Die Verbindung wird an den Pool zurückgegeben, wo sie von einem anderen Funktionsaufruf benötigt wird. Daher ist ihre Lebensdauer länger als die Anweisung. – Frostfyre