java - JDBC 通过 PreparedStatement 中的 executeBatch 调用保证原子操作

标签 java sql oracle jdbc atomic

我有以下域对象:

class Cat  
{  
    String name;  
    int age;  
}

和下面的语句做猫的批量插入:

void insertBulkCats(Collection<Cat> cats)  
{  
    Connection conn = getConnection();  
    PreparedStatement statement = new PreparedStatement();  
    for(Cat cat : cats)  
    {  
       statement.setString(1, cat.getName());  
       statement.setInt(2, cat.getAge());
       statement.addBatch();
    }     
    statement.executeBatch();  
    PreparedStatement mergeStatement = conn.prepareStatement(MERGE_CATS);  
    mergeStatement.execute();
    PreparedStatement dropStatement = conn.prepareStatement(CLEAR_CATS);    
    dropStatement.execute();  
    conn.commit();
}  

这是一个 Oracle 数据库。由于我要执行的步骤是插入所有猫,对我存档的猫进行合并,然后从插入的原始猫中删除所有记录。我担心的是,上面的这种方法不能保证回滚或单独操作的发生。我的问题是如何保证这一切都作为一个原子操作执行?此外,我如何保证没有其他函数接触数据库(就更新 Cat 表而言)不是读取?

最佳答案

原子性是 ACID 的一个特征数据库管理系统。它在 Oracle 中是自动的:运行所有 DML(更新/插入/删除),完成后发出提交。您可以保证操作将保存为不可分割的事务(如果提交失败,则不会保存任何内容)。

在 JDBC 中,您必须确保关闭自动提交

关于并发性,它也是大多数 DBMS 的集成特性,尽管锁定的行为在主要 DBMS 之间可能有所不同。

在 Oracle 中,写入不会阻塞读取,尽管在您提交之前其他事务不会看到您的更改:这种隔离是通过 multi-versionning 实现的. DML 的锁定机制是行级的。只有一个事务可以同时修改一行。 Oracle 中一个工作单元的常见模式是:

  1. 选择要使用子句FOR UPDATE 修改的行。这将锁定这些行,并且在您提交或回滚之前,其他事务将无法修改这些行。
  2. 无需中间提交即可执行所有 DML
  3. promise 成功或在出现错误时回滚。

进一步阅读:更多关于 transaction management , 更多信息 concurrency and locking .

锁定整个表在 Oracle 中很少见,尽管有可能。 LOCK TABLE命令可用于防止其他 session 对整个表的任何修改。

关于java - JDBC 通过 PreparedStatement 中的 executeBatch 调用保证原子操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11669498/

相关文章:

mysql - SQL 左连接错误 - 体育应用

sql - 从一组数据生成每日记录

c++ - 如何在使用 Oracle OCCI 库迭代结果时计算列数?

database - 如果没有 order by 子句,Oracle 中的 FIRST_VALUE() 函数如何处理行?

java - 不确定我是否正确编写了返回 true 或 false 的方法

JavaFX 使 cellFactory 变得通用

java - 服务器发送事件 + Java 与 Spring MVC

Mysql返回不同行中数字的枚举

oracle - 如何使用 %ROWTYPE 获得真实签名

java - "Exception in thread "主要 "<openjpa-1.2.1-r752877:753278 fatal store error> org.apache.openjpa.persistence.RollbackException: near "FOR ""错误