【问题标题】:JDBC guarantee atomic operation via executeBatch call within PreparedStatementJDBC 通过 PreparedStatement 中的 executeBatch 调用保证原子操作
【发布时间】:2016-06-06 16:22:28
【问题描述】:

我有以下域对象:

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

【问题讨论】:

  • 您知道您必须执行您的mergeStatementdropStatement,而不仅仅是准备它们,对吧?
  • @Olaf 是的,我忘了包括这一点,因为我是手工抄写的,显然没有名为 Cat 的表格。更新了:)

标签: java sql oracle jdbc atomic


【解决方案1】:

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

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

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

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

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

更多阅读:更多关于transaction management,更多关于concurrency and locking

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

【讨论】:

  • 有趣。在关闭自动提交方面,在语句或 Connection 对象中设置的位置是什么?
  • 您的 oracle 链接已关闭
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-08
  • 2019-12-17
  • 1970-01-01
  • 1970-01-01
  • 2013-11-14
相关资源
最近更新 更多