【发布时间】:2020-10-25 19:27:09
【问题描述】:
根据 mysql 文档: https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-usagenotes-last-insert-id.html
有时,使用 SELECT LAST_INSERT_ID() 查询可能会很棘手, 因为该函数的值被限定为一个连接。所以,如果其他一些 查询发生在同一个连接上,该值被覆盖。在 另一方面,getGeneratedKeys() 方法的范围是 Statement 实例,因此即使其他查询发生在同一个实例上,它也可以使用 连接,但不在同一个 Statement 实例上。
首先,我考虑LAST_INSERT_ID()。
SQL 函数LAST_INSERT_ID() 是连接安全的,但不是会话/事务/语句安全的。它不能在生产中使用,因为在实际环境中,一个连接中的多个会话/事务/语句非常常见。
然后getGeneratedKeys() 使用 JDBC。当我在 Java 中使用 getGeneratedKeys() 时。我想看看它在数据库中的作用。在使用 JDBC 使用自动增加主键简单插入演示表后,我尝试使用以下语句跟踪 SQL 语句:
SET GLOBAL log_output = 'TABLE';
SET GLOBAL general_log = 'ON';
SELECT * FROM mysql.general_log;
我确定新行已正确插入,getGeneratedKeys() 会带回自动递增的 id。但是,我只发现 JDBC 之前执行的插入语句,以及一些静态数据,如 "SELECT database(),version()..."。
现在,结论是,getGeneratedKeys() 不执行任何 SQL 语句来获取自动递增的 id。然后我找到了另一种可能性,我调试到调用堆栈,请参阅 JDBC get auto-incremented id from an object called OkPacket。它有一个名为last_insert_id 的属性。终于找到了。
我的问题是:
- 真的没有办法使用纯 SQL 语句(不使用 JDBC)获得 STATEMENT SAFE(至少是事务安全)自动递增 id 吗?
-
OkPacket如何在后台工作?它如何获得声明安全自动增加ID?也许它在 MySQL 驱动程序或 MySQL 服务器/客户端协议中调用了一些低级 C 函数?
【问题讨论】:
标签: java mysql jdbc mariadb innodb