如何在ODBC中启动事务?特别是我碰巧在处理SQL Server,但问题可以适用于任何数据源。
在本机T-SQL中,您发出命令:
BEGIN TRANSACTION
--...
COMMIT TRANSACTION
--or ROLLBACK TRANSACTION
在ADO.net中,您可以致电:
DbConnection conn = new SqlConnection();
DbTransaction tx = conn.BeginTransaction();
//...
tx.Commit();
//or tx.Rollback();
在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();
在ADO中,您致电:
Connection conn = new Connection();
conn.BeginTrans();
//...
conn.CommitTrans();
//or conn.RollbackTrans();
对于ODBC,Microsoft在其页面Transactions in ODBC上提供了一个提示:
应用程序调用{{3}}以在管理事务的两种ODBC模式之间切换:
手动提交模式
所有执行的语句都包含在同一个事务中,直到通过调用SQLSetConnectAttr专门停止它为止。
这意味着我只需要知道要传递给 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);
但该页面并未真正提供有关哪个参数将启动事务的任何提示。它可能是:
SQL_COPT_SS_ENLIST_IN_XA
要使用符合XA的事务处理器(TP)开始XA事务,客户端会调用Open Group tx_begin 函数。然后,应用程序使用TRUE的SQL_COPT_SS_ENLIST_IN_XA参数调用 SQLSetConnectAttr ,以将XA事务与ODBC连接相关联。所有相关的数据库活动都将在XA事务的保护下执行。要结束与ODBC连接的XA关联,客户端必须使用FALSE的SQL_COPT_SS_ENLIST_IN_XA参数调用 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);
答案 0 :(得分:4)
ODBC可以在两种模式下运行:AUTOCOMMIT_ON和AUTOCOMMIT_OFF。默认值为AUTOCOMMIT_ON。当Autocommit为ON时,您开始使用与该Connection相关联的会话句柄的每个命令都将自动提交。
让我们看看“手动提交”(别名AUTOCOMMIT_OFF)是如何工作的。
首先你切换AUTOCOMMIT OFF使用类似这样的东西:
if (!SQL_SUCCEEDED(Or=SQLSetConnectAttr(Oc, SQL_ATTR_AUTOCOMMIT,
(SQLPOINTER)SQL_AUTOCOMMIT_OFF,
SQL_IS_UINTEGER))) {
// error handling here
}
其中“Oc”是连接句柄。
第二像往常一样运行所有命令:准备/执行语句,绑定参数等....没有特定的命令来“启动”事务。切换自动提交关闭后的所有命令都是事务的一部分。
第三次您提交:
if (!SQL_SUCCEEDED(Or=SQLEndTran(SQL_HANDLE_DBC, Oc, SQL_COMMIT))) {
// Error handling
}
而且 - 再次 - 从现在开始的所有新命令都自动成为新事务的一部分,您必须使用另一个SQLEndTran命令提交,如上所示。
最后 ...再次切换AUTOCOMMIT_ON:
if (!SQL_SUCCEEDED(Or=SQLSetConnectAttr(Oc, SQL_ATTR_AUTOCOMMIT,
(SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_IS_UINTEGER))) {
// Error Handling
}