Ketika saya melakukan satu baris INSERT
ke tabel yang memiliki AUTO_INCREMENT
kolom saya ingin menggunakan LAST_INSERT_ID()
fungsi untuk mengembalikan nilai baru yang AUTO_INCREMENT
disimpan untuk baris itu.
Karena banyak Microsoft SQL Server devs dan admin tidak diragukan lagi menyadari fungsi yang setara dalam SQL Server ( SCOPE_IDENTITY
dan @@IDENTITY
) belum tanpa masalah .
Saya tahu status dokumen MySQL:
ID yang dihasilkan dipertahankan di server berdasarkan per koneksi . Ini berarti bahwa nilai yang dikembalikan oleh fungsi ke klien yang diberikan adalah nilai pertama yang
AUTO_INCREMENT
dihasilkan untuk pernyataan terbaru yang memengaruhiAUTO_INCREMENT
kolom oleh klien itu . Nilai ini tidak dapat dipengaruhi oleh klien lain, bahkan jika mereka menghasilkanAUTO_INCREMENT
nilai sendiri. Perilaku ini memastikan bahwa setiap klien dapat mengambil ID sendiri tanpa memperhatikan aktivitas klien lain, dan tanpa perlu kunci atau transaksi.
dan bahkan melangkah lebih jauh dengan mengatakan:
Penggunaan
LAST_INSERT_ID()
danAUTO_INCREMENT
kolom secara simultan dari banyak klien benar-benar valid.
Adakah risiko atau skenario yang diketahui yang dapat menyebabkan LAST_INSERT_ID()
tidak mengembalikan nilai yang benar?
Saya menggunakan MySQL 5.5 pada CentOS 5.5 x64 dan Fedora 16 x64 dan mesin InnoDB.
Untuk memperluas lebih lanjut pada poin nomor 2 dalam jawaban yang diberikan oleh DTest:
Pada versi MySQL yang telah saya gunakan, adalah ide yang bagus untuk secara eksplisit mengatur ulang nilai LAST_INSERT_ID sebelum setiap blok kode tempat Anda berencana melakukan penyisipan.
Ini bisa dilakukan seperti ini:
Setelah serangkaian pernyataan di atas dijalankan, Anda akan tahu apakah sisipan memiliki pengaruh dengan memeriksa apakah LAST_INSERT_ID masih disetel ke "some_flag_init_value_of_your_choice" di akhir eksekusi.
Jika tidak, Anda dapat berakhir dengan situasi bermasalah berikut:
Karena sisipan kedua telah gagal , Anda mungkin mengharapkan bahwa panggilan kedua ke LAST_INSERT_ID akan mengembalikan NULL atau bahwa ia akan menghasilkan set hasil kosong (nol baris). Fakta bahwa itu masih mengembalikan pengenal bilangan bulat yang valid dapat menyesatkan Anda untuk berpikir bahwa sisipan kedua SUCCEEDED ketika itu tidak berhasil.
Segala sesuatunya menjadi BAHKAN WEIRDER ketika Anda menganggap bahwa LAST_INSERT_ID akan terus melestarikan dan mengulang id unik yang berhasil terakhir bahkan jika pernyataan insert gagal berikutnya menargetkan tabel yang berbeda dari tabel yang menghasilkan id unik sukses terakhir. Dengan kata lain, Anda memasukkan TA tabel dan mendapatkan id 5, lalu memasukkan TB (tetapi gagal), tetapi Anda masih melihat 5. Berdasarkan itu, Anda berpikir bahwa Anda baru saja membuat baris baru dalam TA dengan id 5 dan baris baru dalam TB dengan id 5, sedangkan pada kenyataannya tidak ada baris dalam TB dengan id 5, atau memang ada baris seperti itu tetapi sebenarnya tidak ada hubungannya dengan kode apa pun yang Anda baru saja berlari.
sumber
last_insert_id()
untuk menilai jika permintaan telah berhasil. Lagipula, ini adalah Id yang dimasukkan terakhir, menyimpan nilai yang Anda butuhkan ketika Anda sudah tahu bahwa Anda telah berhasil.