这是一个答案,而不是我需要在SO中说明的问题。我一直在为这个问题(“如何在将 soci 库与 PostgreSQL 数据库一起使用时关闭自动提交”)苦苦挣扎,并想出了几个解决方案。
在 Oracle 中,默认情况下自动提交选项是关闭的,我们必须soci::session::commit
显式调用以提交我们所做的事务,但在 PostgreSQL 中这是另一种方式,它会在我们执行 sql 语句时立即提交(纠正我,如果我错了)。这将在我们独立编写应用程序数据库时引入问题。soci 库提供soci::transaction
了为了解决这个问题。
soci::transaction
因此,当我们通过提供to 来初始化 a 时soci::session
,它将保存我们所做的事务而不提交到数据库。最后,当我们调用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();
}
但是,执行commit
或rollback
将结束事务tr
,我们需要初始化另一个soci::transaction
以保存我们即将进行的未来事务(创建一个活跃的进行中的事务)。这里有更多有趣的事实soci::transaction
。
soci::transaction
每个soci::session
. _ 如果您初始化另一个,第二个将替换第一个。- 您不能执行多于一个
commit
或rollback
使用一个soci::transaction
. 在您第二次提交或回滚时,您将收到一个异常。 - 您可以初始化 a
transaction
,然后使用session::commit
orsession::rollback
。它将给出与transaction::commit
or相同的结果transaction::rollback
。但是,只要您像往常一样执行单次提交或回滚,事务就会结束。 - 对象对您的范围(执行 sql 并调用提交或回滚的地方)的可见性无关紧要
soci::transaction
,以便保留您所做的数据库事务,直到显式提交或回滚。换句话说,如果 a 有一个transaction
正在进行的活动session
,则 db 事务将一直保持,直到我们明确提交或回滚。 - 但是,如果为
transaction
它创建的实例的生命周期session
结束,我们不能期望数据库事务会停止。 - 如果您每个人都遭受“警告:没有正在进行的事务”,您必须仅使用
soci::transaction::commit
or执行提交或回滚soci::transaction::rollback
。
现在我将发布我想出的解决方案,以便使用任何数据库后端启用显式提交或回滚。