According to mysql doc: https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-usagenotes-last-insert-id.html
At times, it can be tricky to use the SELECT LAST_INSERT_ID() query, as that function's value is scoped to a connection. So, if some other query happens on the same connection, the value is overwritten. On the other hand, the getGeneratedKeys() method is scoped by the Statement instance, so it can be used even if other queries happen on the same connection, but not on the same Statement instance.
First, I consider LAST_INSERT_ID()
.
The SQL function LAST_INSERT_ID()
is connection safe, but not session/transaction/statement safe. It can't be used in production, because in real environment multiple session/transaction/statement in one connection is very common.
Then getGeneratedKeys()
using JDBC. When I'm using getGeneratedKeys()
in Java. I want to see what it does in database. I try to track the SQL statement with the following statements after a simple insert into a demo table with auto increase primary key using JDBC:
SET GLOBAL log_output = 'TABLE';
SET GLOBAL general_log = 'ON';
SELECT * FROM mysql.general_log;
I'm sure the new row is correctly inserted and getGeneratedKeys()
brings the auto-incremented id back. However, I find nothing but just an insert statement which JDBC executed before, and some static data like "SELECT database(),version()..."
.
Now, conclusion is, getGeneratedKeys()
doesn't execute any SQL statement to get auto-incremented id. Then I find another possibility, I debug into call stacks, see JDBC get auto-incremented id from an object called OkPacket
. It has a property called last_insert_id
. Here I find it finally.
My questions are:
- Is there really no way to get a STATEMENT SAFE (at least transaction safe) auto-incremented id using pure SQL statement (without JDBC)?
- How does
OkPacket
work under hood? How does it get a statement safe auto increased id? Maybe it calls some low level C function in MySQL driver or MySQL server/client protocol?