如何在 ODBC 中启动事务?

Ian*_*oyd 5 sql-server winapi odbc

如何在 ODBC 中启动事务?具体来说,我碰巧正在处理 SQL Server,但这个问题可以适用于任何数据源。

在本机 T-SQL 中,您发出以下命令:

BEGIN TRANSACTION
--...
COMMIT TRANSACTION
--or ROLLBACK TRANSACTION
Run Code Online (Sandbox Code Playgroud)

在 ADO.net 中,您可以调用:

DbConnection conn = new SqlConnection();
DbTransaction tx = conn.BeginTransaction();
//...
tx.Commit();
//or tx.Rollback();
Run Code Online (Sandbox Code Playgroud)

在 OLE DB 中您可以调用:

IDBInitialize init = new MSDASQL();
IDBCreateSession session = (init as IDBCreateSession).CreateSession();
(session as ITransactionLocal).StartTransaction(ISOLATIONLEVEL_READCOMMITTED, 0, null, null);
//...
(session as ITransactionLocal).Commit();
//or (session as ITransactionLocal).Rollback();
Run Code Online (Sandbox Code Playgroud)

在 ADO 中您可以调用:

Connection conn = new Connection();
conn.BeginTrans();
//...
conn.CommitTrans();
//or conn.RollbackTrans();
Run Code Online (Sandbox Code Playgroud)

ODBC 怎么样?

对于 ODBC,Microsoft 在其页面Transactions in ODBC上给出了提示:

应用程序调用SQLSetConnectAttr在管理事务的两种 ODBC 模式之间切换:

这意味着我只需要知道要传递给SQLSetConnectAttr 的参数:

HENV environment;
SQLAllocEnv(&environment);
HDBC conn;
SQLAllocConnect(henv, &conn);

SQLSetConnectAttr(conn, {attribute}, {value}, {stringLength});
//...
SQLEndTran(SQL_HANDLE_ENV, environment, SQL_COMMIT);
//or SQLEndTran(SQL_HANDLE_ENV, environment, SQL_ROLLBACK);
Run Code Online (Sandbox Code Playgroud)

但该页面并没有真正给出任何关于哪个参数将启动事务的提示。有可能:

SQL_COPT_SS_ENLIST_IN_XA

要使用 XA 兼容的事务处理器 (TP) 开始 XA 事务,客户端调用 Open Group tx_begin函数。然后,应用程序使用 SQL_COPT_SS_ENLIST_IN_XA 参数 TRUE 调用 SQLSetConnectAttr,以将 XA 事务与 ODBC 连接关联起来所有相关的数据库活动都将在XA事务的保护下执行。要结束与 ODBC 连接的 XA 关联,客户端必须使用 SQL_COPT_SS_ENLIST_IN_XA 参数 FALSE调用SQLSetConnectAttr 。有关详细信息,请参阅 Microsoft 分布式事务协调器文档。

但由于我从未听说过 XA,也不需要运行 MSDTC,所以我不认为就是这样。


丸尾回答了。但需要澄清的是:

HENV environment;
SQLAllocEnv(&environment);
HDBC conn;
SQLAllocConnect(henv, &conn);

SQLSetConnectAttr(conn, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, SQL_IS_UINTEGER);
//...
SQLEndTran(SQL_HANDLE_ENV, environment, SQL_COMMIT);
//or SQLEndTran(SQL_HANDLE_ENV, environment, SQL_ROLLBACK);

SQLSetConnectAttr(conn, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON, SQL_IS_UINTEGER);
Run Code Online (Sandbox Code Playgroud)

mau*_*uro 7

ODBC 可以在两种模式下运行:AUTOCOMMIT_ON 和 AUTOCOMMIT_OFF。默认为 AUTOCOMMIT_ON。当自动提交打开时,您开始使用与该连接关联的会话句柄的每个命令都将被自动提交。

让我们看看“手动提交”(别名 AUTOCOMMIT_OFF)是如何工作的。

首先,使用如下命令关闭 AUTOCOMMIT:

if (!SQL_SUCCEEDED(Or=SQLSetConnectAttr(Oc, SQL_ATTR_AUTOCOMMIT,   
                      (SQLPOINTER)SQL_AUTOCOMMIT_OFF,
                       SQL_IS_UINTEGER))) {
// error handling here
}
Run Code Online (Sandbox Code Playgroud)

其中“Oc”是连接句柄。

其次,您照常运行所有命令:准备/执行语句、绑定参数等...没有特定的命令来“启动”事务。将自动提交关闭后的所有命令都是事务的一部分。

第三你承诺:

if (!SQL_SUCCEEDED(Or=SQLEndTran(SQL_HANDLE_DBC, Oc, SQL_COMMIT))) {
// Error handling
}
Run Code Online (Sandbox Code Playgroud)

再次强调,从现在开始,所有新命令都会自动成为新事务的一部分,您必须使用另一个 SQLEndTran 命令来提交该事务,如上面所示。

最后...再次切换 AUTOCOMMIT_ON :

if (!SQL_SUCCEEDED(Or=SQLSetConnectAttr(Oc, SQL_ATTR_AUTOCOMMIT, 
                  (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_IS_UINTEGER))) {
 // Error Handling
}
Run Code Online (Sandbox Code Playgroud)