1

我有以下域对象:

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 表进行更新而言)?

4

1 回答 1

8

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

在 JDBC 中,您必须确保关闭 autocommit

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

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

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

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

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

于 2012-07-26T13:08:01.153 回答