繁体   English   中英

使用SOCI C ++在PostgreSQL中设置自动提交

[英]Set autocommit off in PostgreSQL with SOCI C++

这是一个答案,而不是我需要在SO中陈述的问题。 我很难解决这个问题(“如何在使用带有PostgreSQL数据库的社交库时关闭自动提交”)并提出了几个解决方案。

在Oracle中,默认情况下自动提交选项已关闭,我们必须显式调用soci::session::commit来提交我们所做的事务,但在PostgreSQL中这是另一种方式,它会在我们执行时立即提交sql语句(纠正我,如果我错了)。 这将在我们独立编写应用程序数据库时引入问题。 soci库提供soci::transaction以解决这个问题。

因此,当我们通过提供soci::session初始化一个soci::transaction ,它将保留我们所做的事务而不需要提交到数据库。 最后,当我们调用soci::transaction::commit它会将更改提交给数据库。

soci::session sql(CONNECTION_STRING);
soci::transaction tr(sql);
try {
    sql << "insert into soci_test(id, name) values(7, \'John\')";
    tr.commit();
}
catch (std::exception& e) {
    tr.rollback();
}

但是,执行commitrollback将结束事务tr ,我们需要初始化另一个soci::transaction ,以便保存我们即将进行的未来事务(以创建一个活动进行中的事务)。 以下是关于soci::transaction更多有趣事实。

  1. 每个soci::session只能有一个soci::transaction实例。 如果你初始化另一个,第二个将替换第一个。
  2. 您不能使用soci::transaction执行多次commitrollback 您将在第二次提交或回滚时收到异常。
  3. 您可以初始化transaction ,然后使用session::commitsession::rollback 它将提供与transaction::committransaction::rollback相同的结果。 但是,只要像往常一样执行单个提交或回滚,事务就会结束​​。
  4. soci::transaction对象的可见性与您的作用域(执行sql并调用commit或rollback)的可见性无关,以便在显式提交或回滚之前保存您所做的db事务。 换句话说,如果session中存在正在进行的活动transaction ,则db事务将一直保持到我们显式提交或回滚为止。
  5. 但是,如果为session创建的transaction实例的生命周期结束,我们不能指望数据库事务将停止。
  6. 如果您每个人都遭受“警告:没有正在进行的事务”,则必须仅使用soci::transaction::commitsoci::transaction::rollback执行提交或soci::transaction::rollback

现在我将发布我提出的解决方案,以便使用任何数据库后端启用显式提交或回滚。

这是我提出的解决方案。

namespace mysociutils
{
    class session : public soci::session
    {
    public:
        void open(std::string const & connectString)
        {
            soci::session::open(connectString);
            tr = std::unique_ptr<soci::transaction>(new soci::transaction(*this));
        }

        void commit()
        {
            tr->commit();
            tr  = std::unique_ptr<soci::transaction>(new soci::transaction(*this));
        }

        void rollback()
        {
            tr->rollback();
            tr  = std::unique_ptr<soci::transaction>(new soci::transaction(*this));
        }        

        void ~session()
        {
            tr->rollback();
        }

    private:
        std::unique_ptr<soci::transaction> tr;
    };
}

执行提交或回滚时,初始化一个新的soci::transaction 现在,您可以取代你soci::session sqlmysociutils::session sql和享受SET AUTOCOMMIT OFF

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM