transaction()不会增加@@ TRANCOUNT?

时间:2017-11-17 15:00:05

标签: sql-server database qt transactions

MS SQL SERVER 2008. Qt + ODBC。

我正在尝试通过回滚最高级别的事务来回滚数据库中的一些更改(在内部进行)。但看起来我的第二个db.transaction()调用没有增加@@ TRANCOUNT和第一个提交(内部)关闭事务completly。因此,外部事务级别中的下一个rollback命令才会被忽略。

一些例子。每次操作后,已注释的字符串显示从DB收到的@@ TRANCOUNT:

db.transaction();                                       //@@TRANCOUNT = 0
query->exec("INSERT INTO TestOnly (Value) VALUES('1')");//@@TRANCOUNT = 1
db.transaction();                                       //@@TRANCOUNT = 1
query->exec("INSERT INTO TestOnly (Value) VALUES('2')");//@@TRANCOUNT = 1
db.commit();                                            //@@TRANCOUNT = 0
query->exec("INSERT INTO TestOnly (Value) VALUES('3')");//@@TRANCOUNT = 0
db.rollback();                                          //@@TRANCOUNT = 0

测试代码:

...
db = QSqlDatabase::addDatabase("QODBC3");
...
query = new QSqlQuery(db);
...

bool ok;
ok = db.transaction(); qDebug() << "Start transaction" << " result = " << ok << "; errorText: " << db.lastError().text();
PrintTranCount(); //0

query->exec("INSERT INTO TestOnly (Value) VALUES('1')");
PrintTranCount(); //1

ok = db.transaction(); qDebug() << "Start transaction" << " result = " << ok << "; errorText: " << db.lastError().text();
PrintTranCount(); //2

query->exec("INSERT INTO TestOnly (Value) VALUES('2')");
PrintTranCount(); //3

ok = db.commit(); qDebug() << "Commit transaction" << " result = " << ok << "; errorText: " << db.lastError().text();
PrintTranCount(); //4

query->exec("INSERT INTO TestOnly (Value) VALUES('3')");
PrintTranCount(); //5

ok = db.rollback();  qDebug() << "Rollback transaction" << " result = " << ok << "; errorText: " << db.lastError().text();
PrintTranCount(); //6

调试输出:

Start transaction  result =  true ; errorText:  " "  
Transaction Count   0: 0  
Transaction Count   1: 1   
Start transaction  result =  true ; errorText:  " "   
Transaction Count   2: 1   
Transaction Count   3: 1   
Commit transaction  result =  true ; errorText:  " "  
Transaction Count   4: 0  
Transaction Count   5: 0   
Rollback transaction  result =  true ; errorText:  " "  
Transaction Count   6: 0   

PrintTranCount()函数:

static int Num = 0;
query->exec("SELECT @@TRANCOUNT");query->first();
qDebug() << "Transaction Count  "<< Num << ": " <<query->value(0).toInt();
Num++;

第二次交易后,交易柜台(@@ TRANCOUNT)没有增加到2的原因是什么?我没有正确理解交易柜台的想法?或者数据库/驱动程序设置有问题?也许我错过了我的示例代码中的一些错误?

我会感激任何提示。对不起谷歌翻译:)

1 个答案:

答案 0 :(得分:0)

通过查看源代码解决了所有问题

db.transaction()不会向数据库发送任何“begin tran”命令(至少使用ODBC驱动程序)。此功能仅将提交模式更改为“manual commit mode”。之后,首先db.commit()确认所有更改(通过发送“SQLEndTran”命令)并再次将模式更改回“自动提交模式”。

要使用@@ TRANCOUNT的“嵌套”(非真正嵌套)事务,只需手动将“tran begin”/“commit”/“rollback”命令发送到数据库即可。在我的例子中:

query->exec("begin tran");                              //@@TRANCOUNT = 1
query->exec("INSERT INTO TestOnly (Value) VALUES('1')");//@@TRANCOUNT = 1
query->exec("begin tran");                              //@@TRANCOUNT = 2
query->exec("INSERT INTO TestOnly (Value) VALUES('2')");//@@TRANCOUNT = 2
query->exec("commit");                                  //@@TRANCOUNT = 1
query->exec("INSERT INTO TestOnly (Value) VALUES('3')");//@@TRANCOUNT = 1
query->exec("rollback");                                //@@TRANCOUNT = 0