【发布时间】:2018-05-01 09:39:49
【问题描述】:
MS SQL SERVER 2008。Qt + ODBC。
我正在尝试通过回滚最高级别的事务来回滚数据库中的一些更改(在内部进行的)。但看起来我的第二个 db.transaction() 调用没有增加 @@TRANCOUNT 并且第一次提交(内部)完全关闭事务。因此,外部事务级别的下一个回滚命令就被忽略了。
一些例子。每次操作后,注释字符串显示从 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 有什么原因吗?我没有正确理解事务计数器的概念?还是数据库/驱动程序设置有问题?也许我的示例代码中有一些我错过的错误?
如有任何提示,我将不胜感激。对不起谷歌翻译:)
【问题讨论】:
-
SQL Server 中没有嵌套事务,因为任何“内部”事务的提交都不会提交任何内容(仅增加 @@trancount),任何“内部”回滚都会回滚。
-
对不起,我没有正确描述问题。在我的情况下(上面描述的 '1' '2' '3' 插入)根本没有任何回滚操作。根据您评论中的一篇文章,外部回滚应该取消在内部事务中提交的操作。但这不会发生。我在 TestOnly 表中有所有三行。我决定立即询问事务计数器,因为看起来数据库根本没有启动内部事务。
-
我不知道你的编程语言,但如果你使用 T-SQL 并编写 3 个这样的插入: INSERT INTO TestOnly (Value) VALUES('1'); INSERT INTO TestOnly (Value) VALUES('2');INSERT INTO TestOnly (Value) VALUES('3') 会有三个事务,SQL Server 以自动提交模式运行
-
要在一个事务中获取所有这些,您应该显式打开事务:BEGIN TRAN INSERT INTO TestOnly (Value) VALUES('1');插入TestOnly(值)VALUES('2');插入TestOnly(值)VALUES('3');提交
标签: sql-server database qt transactions