Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 事务()不增加@@TRANCOUNT?_Sql Server_Database_Qt_Transactions - Fatal编程技术网

Sql server 事务()不增加@@TRANCOUNT?

Sql server 事务()不增加@@TRANCOUNT?,sql-server,database,qt,transactions,Sql Server,Database,Qt,Transactions,MS SQL SERVER 2008。Qt+ODBC 我试图通过回滚最高级别的事务来回滚在数据库内部所做的一些更改。但看起来我的第二个db.transaction调用并没有增加@TRANCOUNT并完全提交第一个内部关闭事务。因此,外部事务级别中的下一个回滚命令被忽略 举个例子。注释字符串显示每次操作后从DB接收的@@TRANCOUNT: db.transaction(); //@@TRANCOUNT = 0 query

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
PrintTranCount函数:

static int Num = 0;
query->exec("SELECT @@TRANCOUNT");query->first();
qDebug() << "Transaction Count  "<< Num << ": " <<query->value(0).toInt();
Num++;
第二次交易后,交易计数器@TRANCOUNT没有增加到2有什么原因吗?我没有正确理解交易柜台的概念?或者数据库/驱动程序设置有问题?也许我的示例代码中有一些我遗漏的错误

如有任何提示,我将不胜感激。很抱歉谷歌翻译:

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

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

若要将nestednot真正嵌套的事务与@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
通过查看源代码解决了所有问题:

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

若要将nestednot真正嵌套的事务与@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

SQL Server中没有嵌套事务,因为任何内部事务的提交都不会提交任何内容,只会增加@@trancount,任何内部回滚都会回滚。请阅读此处:对不起,我没有正确描述问题。在我使用上述“1”“2”“3”插入的情况下,根本没有回滚任何操作。根据您评论中的一篇文章,外部回滚应该取消在内部事务中提交的操作。但事实并非如此。我在TestOnly表中有所有三行。我决定立即询问事务计数器,因为看起来数据库根本没有启动内部事务。我不知道您的编程语言,但如果您使用t-SQL并像这样编写3个插入:插入到TestOnly值'1';插入TestOnly值'2';插入到TestOnly值'3'将有三个事务,SQL Server在自动提交模式下运行要在一个事务中获取所有事务,您应该显式打开事务:BEGIN TRAN INSERT INTO TestOnly值'1';插入TestOnly值'2';插入TestOnly值'3';提交SQL Server中没有嵌套事务,因为任何内部事务的提交都不会提交任何内容,只会增加@@trancount,任何内部回滚都会回滚。请阅读此处:对不起,我没有正确描述问题。在我使用上述“1”“2”“3”插入的情况下,根本没有回滚任何操作。根据您评论中的一篇文章,外部回滚应该取消在内部事务中提交的操作。但事实并非如此。我在TestOnly表中有所有三行。我决定立即询问事务计数器,因为看起来数据库根本没有启动内部事务。我不知道您的编程语言,但如果您使用t-SQL并像这样编写3个插入:插入到TestOnly值'1';插入TestOnly值'2';插入到TestOnly值'3'将有三个事务,SQL Server在自动提交模式下运行要在一个事务中获取所有事务,您应该显式打开事务:BEGIN TRAN INSERT INTO TestOnly值'1';插入TestOnly值'2';插入TestOnly值'3';犯罪