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

Woo*_*Moo 1 java sql oracle jdbc atomic

我有以下域对象:

class Cat  
{  
    String name;  
    int age;  
}
Run Code Online (Sandbox Code Playgroud)

以及以下声明来批量插入猫:

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();
}  
Run Code Online (Sandbox Code Playgroud)

这是一个Oracle数据库.我想要执行的步骤是插入所有猫,对我存档的猫进行合并,然后从插入的原始猫中删除所有记录.我担心的是,上述方法不能保证回滚或单独操作.我的问题是我如何保证这可以作为一个原子操作执行?另外,我如何保证没有其他功能接触数据库(对Cat表进行更新)不读取?

Vin*_*rat 8

原子性是ACID DBMS的一个特征.它在Oracle中是自动的:一旦完成提交,就运行所有DML(更新/插入/删除).您可以保证将操作保存为不可分割的事务(如果提交失败则不保存任何内容).

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

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

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

  1. 使用该子句选择要修改的行FOR UPDATE.这会对行进行锁定,而其他事务在提交或回滚之前将无法修改这些行.
  2. 在没有中间提交的情况下执行所有DML
  3. 在出现错误时提交成功或回滚.

进一步阅读:更多关于事务管理,更多关于并发和锁定.

尽管有可能,但在Oracle中很少锁定整个表.在LOCK TABLE命令可以被用来防止从其他会话任何修改整个表.