我正在为我们的产品将PostgreSQL从8.1.3升级到9.2.9。我们使用unixODBC 2.2.11来访问数据库,它是用C ++语言编写的。升级后我收到以下错误:
"LOCK TABLE can only be used in transaction blocks".
我检查了release note的PostgreSQL,发现它禁止在事务块外面使用LOCK TABLE。
我检查了代码,发现我们在转换中锁定了一些表格,示例代码:
db_connect.BeginTrans();
rtn_code = LockTable(db_connect, Setting_Filter.m_backup_tables, LOCK_SHARE);
...
db_connect.Commit();
我们使用以下api在BeginTrans()中创建隐式事务:
int BeginTrans()
{
return SQLSetConnectAttr( m_ConHandle,SQL_ATTR_AUTOCOMMIT,(SQLPOINTER)SQL_AUTOCOMMIT_OFF, 0 );
}
我们在LockTable()函数中执行以下锁表sql:
lock table %s in share mode
我的问题是:
这是否意味着BeginTrans()在Postgres 9.2中没有成功创建交易?
我注意到我们经常使用'BEGIN TRANSATION';在PL / SQL中,unixODBC中是否有任何相应的API可以明确启动事务?
答案 0 :(得分:1)
此问题已通过显式调用事务来修复,例如:
int Commit()
{
Execute("commit");
int rt=SQLEndTran( SQL_HANDLE_DBC, m_ConHandle, SQL_COMMIT );
SQLSetConnectAttr( m_ConHandle,SQL_ATTR_AUTOCOMMIT,(SQLPOINTER)SQL_AUTOCOMMIT_ON, 0 );
return rt;
}
int Rollback()
{
Execute("rollback");
int rt=SQLEndTran( SQL_HANDLE_DBC, m_ConHandle, SQL_ROLLBACK );
SQLSetConnectAttr( m_ConHandle,SQL_ATTR_AUTOCOMMIT,(SQLPOINTER)SQL_AUTOCOMMIT_ON, 0 );
return rt;
}
int BeginTrans()
{
SQLSetConnectAttr( m_ConHandle,SQL_ATTR_AUTOCOMMIT,(SQLPOINTER)SQL_AUTOCOMMIT_OFF, 0 );
return Execute("begin transaction");
}