使用 Oracle OCCI 回滚事务

Posted

技术标签:

【中文标题】使用 Oracle OCCI 回滚事务【英文标题】:Rolling back transaction with Oracle OCCI 【发布时间】:2014-09-16 07:34:40 【问题描述】:

我的代码类似于下面的简单示例,它试图在发生错误时回滚数据库写入。但是,似乎有一半的数据留在了数据库中,而不是被删除/回滚。

statement->setAutoCommit(false);
statement->setMaxIterations(3);

int counter = 1;
try

    statement->setInt(1, 1);
    statement->addIteration();

    statement->setInt(1, 2);
    statement->addIteration();

    statement->setInt(1, 3);
    statement->executeUpdate();

    statement->setInt(1, 4);
    statement->addIteration();

    statement->setInt(1, 2); // ERROR HERE (Unique constraint)
    statement->addIteration();

    statement->setInt(1, 6);
    statement->executeUpdate();

    connection->commit();

catch (oracle::occi::SQLException ex)

    connection->rollback();
    connection->terminateStatement(statement);
    throw DatabaseException(ex.what());

如果我得到一个 Oracle 错误,那么我想回滚当前事务,以便没有写入任何行。但是,这似乎无法正常工作。

我有一个写到一半失败,它没有成功回滚行。我最终将一半的数据写入数据库。

setAutoCommit(false)connection->rollback() 命令有什么遗漏吗?

【问题讨论】:

我没用过Oracle,但是最后一条语句后面的语句不需要commit吗?据我所知,只有在执行 commit 语句后,更改才会在 DB 上永久生效。 对不起,你是对的。我会将它添加到我的示例中。不幸的是,这不是我要解决的问题,这里的问题是它正在提交而不是回滚。 哦,我无法为您提供帮助。但是,您是否尝试过创建保存点并回滚到该保存点?你确定在唯一约束失败的那一行调用回滚命令吗? 【参考方案1】:

这可能是batch error processing 的副作用,如果您希望在错误时引发异常,您应该尝试调用 setBatchErrorMode(false)。否则,您也可以使用批处理错误模式并检查收集的错误并决定是否要提交或回滚

【讨论】:

有趣,我会试一试批处理错误。我相信batchErrorMode默认是假的,但我会在周一试一试 @SamuelO'Malley 进展如何? 感谢@Falco,它现在可以工作了,我将 batchErrorMode 设置为 true 并明确处理了语句级错误。

以上是关于使用 Oracle OCCI 回滚事务的主要内容,如果未能解决你的问题,请参考以下文章

oracle 提交事务后为啥不能撤销或回滚,不是有撤销段吗

关于oracle 触发器,与事务回滚

Oracle 事务操作(事务的回滚与提交)

Oracle的表创建和事务管理

Webservice 中的 Oracle 事务回滚

oracle中DDL和DML能在同一事务并一同回滚吗