0
Qt 4.8.3 및 MySQL ODBC 3.51 드라이버를 사용하고 있습니다. 두 번째 테이블의 고유 ID가 중복되어 트랜잭션이 실패하면 첫 번째 테이블의 삽입이 롤백되지 않습니다. 누구든지 오류를 발견 할 수 있습니까?왜 내 거래가 롤백되지 않습니까? Qt Mysql ODBC 드라이버
struct Property //see OMG's Property Service
{
std::string name;
boost::any value;
Property();
Property(const std::string &inName, const boost::any &inValue):name(inName),value(inValue){}
};
Property myFunction(QSqlDatabase &db, int amount)
{
assert(db.driver()->hasFeature(QSqlDriver::Transactions) == true);
db.transaction();
QSqlQuery query(db);
Property ret("MyPropertyTag",0);
try{
query.exec("LOCK TABLES table1 WRITE, table2 WRITE");
if(query.lastError().isValid()) { throw std::exception(query.lastError().text().toAscii()); }
for(int i=0;i<amount;i++)
{
query.exec("INSERT INTO table1 (someUniqueValue, newestId, Created) VALUES ('"+QString::number(i)+"', '1', NOW())");
if(query.lastError().isValid()) { throw std::exception(query.lastError().text().toAscii()); }
query.exec("SELECT id FROM table1 WHERE someUniqueValue = '"+QString::number(i)+"'");
if(query.lastError().isValid()) { throw std::exception(query.lastError().text().toAscii()); }
if(query.next() == false) { throw std::exception("no result for insert id"); }
auto Id1 = query.value(0).toString();
query.exec("INSERT INTO table2 (table1_id, Changed, Created) VALUES ('"+Id1+"', NOW(), NOW())");
if(query.lastError().isValid()) { throw std::exception(query.lastError().text().toAscii()); }
query.exec("SELECT Id, table1_id FROM table2 ORDER BY Id DESC LIMIT 1");
if(query.lastError().isValid()) { throw std::exception(query.lastError().text().toAscii()); } //lets say this throws
if(query.next() == false || query.value(1).toString() != Id1) { throw std::exception("no result for inserted id"); }
auto Id2 = query.value(0).toString();
query.exec("UPDATE table1 SET newestId = '"+Id2+"' WHERE Id = '"+Id1+"'");
if(query.lastError().isValid()) { throw std::exception(query.lastError().text().toAscii()); }
}
db.commit();
ret.value = amount;
} catch(std::exception &e) {
query.finish();
db.rollback();
ret.value = std::string("error:") + e.what();
}
query.exec("UNLOCK TABLES");
query.finish();
return ret;
}
테이블은 Innodb입니까?, 자동 커밋 = 0입니까 (이 것에 대해서는 확실하지 않습니다)? – jcho360
좋은 생각, 그 showodopper 것입니다 그 innodb 경우 체크해야 할 것입니다 ... – odinthenerd
테이블 자동 응답 = 1, 그래서 내 소식 (대답으로 게시하고 받아 들일 것입니다) 좋은 소식을 발견 좋은 소식 MyISAM 있습니다 나쁜 소식 나는 그들을 바꿀 수 없다. 쿼리에서 내 세션에 대해 autocommit = 0을 설정할 수 있습니까? (미안하지만 지금까지 innoDB로만 작업했다.) – odinthenerd