【问题标题】:LOCK TABLE can only be used in transaction blocksLOCK TABLE 只能在事务块中使用
【发布时间】:2014-11-26 09:20:45
【问题描述】:

我正在为我们的产品将 PostgreSQL 从 8.1.3 升级到 9.2.9。我们使用 unixODBC 2.2.11 访问数据库,它是用 C++ 语言编写的。升级后出现以下错误:

"LOCK TABLE can only be used in transaction blocks".

我检查了 PostgreSQL 的 release note,发现它不允许在事务块之外使用 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

我的问题是:

  1. 这是否意味着 BeginTrans() 在 Postgres 9.2 中没有成功创建事务?

  2. 我注意到我们经常使用“BEGIN TRANSATION;”在PL/SQL中,unixODBC中是否有相应的API来显式启动事务?

【问题讨论】:

  • 查看TXID_CURRENT() 在每次调用BeginTransLockTableCommit 之前和之后返回的内容。

标签: postgresql transactions locking unixodbc


【解决方案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");
    }

【讨论】:

    猜你喜欢
    • 2014-06-25
    • 1970-01-01
    • 2014-06-05
    • 2019-08-29
    • 2011-06-18
    • 2017-02-18
    • 2018-10-03
    • 2018-09-02
    相关资源
    最近更新 更多