【问题标题】:What happens exactly when we commit?当我们提交时会发生什么?
【发布时间】:2019-02-26 23:16:34
【问题描述】:

我试图了解我们提交时究竟会发生什么

Connection conn=new Connection();
conn.setAutoCommit(false);
PreparedStatement ps=connection.prepareStaement("insert statement 1");
ps.executeUpdate();
PreparedStatement ps2=connection.prepareStaement("insert statement 2");
ps2.executeUpdate();
conn.commit();
conn.close();

这两条准备好的语句将如何到达数据库?

它们会合并到一个数据库调用中吗?还是将它们单独插入? 我的印象是,他们将一次调用数据库。数据库收到如下内容:

START TRANSACTION
insert statement 1
insert statement 2
COMMIT

还有,上一个和这个有什么不同,这个上发生了多少次调用:

Connection conn=new Connection();
conn.setAutoCommit(false);
PreparedStatement ps=connection.prepareStaement("insert statement ?");
ps.setString(1,"1");
ps.addBatch();
ps.setString(1,"2");
ps.addBatch();
ps.executeBatch();
conn.commit();
conn.close();

【问题讨论】:

  • 他们将是两个电话。您可以通过导致第一次插入失败(即插入重复的主键或其他内容)来尝试此操作
  • 来自Oracle documentation使自上次提交/回滚以来所做的所有更改永久化,并释放此 Connection 对象当前持有的所有数据库锁。正如您自己测试的那样,只有一个事务,但更新将逐个命令完成。
  • 既然executeUpdate()返回一个更新计数,表示该语句更新了多少条记录,如果它在调用commit之前不执行该语句怎么办? --- ps.executeUpdate()ps2.executeUpdate()conn.commit() 是对数据库的 3 次单独调用。
  • @Andreas 请查看更新。谢谢!
  • 批处理的全部意义在于收集要一起执行的语句,以节省数据库的周转时间,那么您认为会发生什么? ps.executeBatch()conn.commit() 是对数据库的 2 次单独调用。

标签: java sql oracle jdbc connection


【解决方案1】:

除了连接/断开,第一个场景有5个数据库调用(prepare、execute、prepare、execute、commit),第二个场景有3个(prepare、execute、commit)。实际上这有点偏颇:为了使示例具有可比性,您需要在第一个场景中运行相同的语句两次,从而节省一个准备。此外,正如Andreas 所评论的那样,一些驱动程序可能不会发出数据库调用以进行准备,而是将其与第一次执行结合起来。

无论如何,从概念上讲,第二个场景中的数据库调用比第一个场景少一个

事务是一种服务器端功能。使用事务时,对数据库的更改仅对执行它们的会话可见。当调用COMMIT 时,它们将变为永久的,并且对其他用户可见。另一方面,拥有会话可以选择ROLLBACK,这基本上意味着:我明确放弃自上次COMMIT以来所做的更改。您可以看到您的每个代码 sn-ps 都发生在单个数据库事务中。从这个角度来看,它们并没有什么不同。

从客户端到服务器的每次调用都需要一次网络往返,这在运行大量小型操作(例如,一堆INSERTs)时可能会很昂贵。这就是 batches 发挥作用的地方:它们允许在对数据库的一次调用中执行多个操作。在这方面,第二个代码 sn-p 可能会更好地扩展,因为无论要处理的记录数量如何,它都会执行相同数量的数据库调用。

【讨论】:

  • "Prepare" 可能是也可能不是数据库调用,这完全取决于 JDBC 驱动程序。由于调用代价高昂,大多数 JDBC 驱动程序会将任何实际准备推迟到第一次执行,因此准备和执行可以组合成一个自调用。所以我不同意你的观点,说第一个场景是 3 个电话,第二个是 2 个电话。
  • @Andreas :是的,同意,我编辑了我的帖子来提及这一点。不过,这并没有改变我回答的整体逻辑。
  • @GMB 什么是执行,什么是提交? “执行”是否在数据库上调用插入记录?我的理解是在“提交”之前没有插入任何记录。或者我们是否在多个调用中发送交易,即;调用开始事务,调用执行,调用提交?非常感谢
  • @super7egazi :是的,执行是对数据库的调用。记录被插入,但只对拥有的会话可见,直到调用 COMMIT(或 ROLLBACK)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-10
  • 2011-04-17
  • 1970-01-01
  • 2013-04-18
  • 2014-03-31
  • 2018-05-03
相关资源
最近更新 更多