如果我有以下2项功能:
int AccessDb::InsertColValue(string tableName, string col, string val)
{
try
{
sql::Statement *stmt;
bool ret;
if ((nomTable != "") && (col != "") && (val != ""))
{
string query = "INSERT INTO " + tableName + "(" + col + ") values (";
query += val + ");";
stmt = con->createStatement();
ret = stmt->execute(query);
}
delete stmt;
return 0;
}
catch (sql::SQLException &e)
{
return -1;
}
}
和
long AccessDb::LastInsertId()
{
try
{
sql::Statement *stmt;
sql::ResultSet *res;
string query = "SELECT LAST_INSERT_ID() AS LAST_ID";
stmt = con->createStatement();
res = stmt->executeQuery(query);
delete stmt;
long lastId;
while (res->next())
{
lastId = res->getInt("LAST_ID");
}
return lastId;
}
catch (sql::SQLException &e)
{
return -1;
}
}
如果我编写以下行并且id是由数据库自动生成的话,我可以确定LastInsertId()的返回总是给我正确的id吗?
AccessDb adb; // initialize the connexion with the db
int ret = adb.InsertColValue("people", "name", "John");
if (ret == 0)
long lastId = adb.LastInsertId();
如果之前的代码同时在其他地方被调用,我的lastId变量中的值是否可以错误?如果是的话,我是否必须在桌面上使用锁定和解锁来避免这种或其他解决方案?
答案 0 :(得分:2)
以下是文档的内容:
生成的ID在服务器上维护 每个连接基础。这意味着返回的值 给定客户端的函数是生成的第一个AUTO_INCREMENT值 对于影响AUTO_INCREMENT列的最新语句 客户。此值不受其他客户端的影响,即使它们也是如此 生成自己的AUTO_INCREMENT值。此行为可确保 每个客户端都可以检索自己的ID而无需担心 其他客户的活动,无需锁或 交易。
因此,除非您自己的客户端代码共享多个线程之间的连接(看起来您不是,因为您的代码中没有互斥锁或锁),您可以确定SELECT LAST_INSERT_ID()isn'与任何其他连接或客户混淆。
我找不到C ++ mysql库的文档,但验证ret = stmt->execute(query);
函数中InsertColValue()
的返回值是什么意思,这样你才能确定唯一可能的失败方式插入任何内容都是在抛出异常时。