dalam kasus menggunakan PreparedStatement dengan satu koneksi umum tanpa kumpulan apa pun, dapatkah saya membuat ulang instance untuk setiap operasi dml / sql yang mempertahankan kekuatan pernyataan yang disiapkan?
Maksudku:
for (int i=0; i<1000; i++) {
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setObject(1, someValue);
preparedStatement.executeQuery();
preparedStatement.close();
}
dari pada:
PreparedStatement preparedStatement = connection.prepareStatement(sql);
for (int i=0; i<1000; i++) {
preparedStatement.clearParameters();
preparedStatement.setObject(1, someValue);
preparedStatement.executeQuery();
}
preparedStatement.close();
pertanyaan saya muncul karena saya ingin memasukkan kode ini ke dalam lingkungan multithread, dapatkah Anda memberi saya beberapa saran? Terima kasih
java
jdbc
prepared-statement
Plume Baja
sumber
sumber
sql
tidak berubah dengan in the loop? jika kueri itu tidak berubah untuk setiap iterasi loop, lalu mengapa Anda membuat yang baruPreparedStatement
untuk setiap iterasi (di cuplikan kode pertama)? Apakah ada alasan untuk melakukannya?Jawaban:
Cara kedua sedikit lebih efisien, tetapi cara yang jauh lebih baik adalah mengeksekusinya secara berkelompok:
Namun, Anda bergantung pada implementasi driver JDBC, berapa banyak batch yang dapat Anda jalankan sekaligus. Misalnya, Anda mungkin ingin mengeksekusinya setiap 1000 batch:
Mengenai lingkungan multithread, Anda tidak perlu khawatir tentang hal ini jika Anda memperoleh dan menutup koneksi dan pernyataan dalam cakupan sesingkat mungkin di dalam blok metode yang sama sesuai dengan idiom JDBC normal menggunakan pernyataan coba-dengan-sumber daya seperti yang ditunjukkan di cuplikan di atas.
Jika kumpulan tersebut bersifat transaksional, maka Anda ingin menonaktifkan koneksi otomatis dan hanya melakukan transaksi saat semua kumpulan selesai. Jika tidak, hal itu dapat mengakibatkan database kotor ketika kelompok pertama dari batch berhasil dan kemudian tidak.
sumber
inside the same method block
- maksud Anda bahwa setiap utas akan memiliki tumpukannya sendiri dan koneksi serta pernyataan ini berada dalam tumpukan dari satu sisi dan dari sumber data lain akan memberikan setiap panggilan baru dari executeFunction (== every thread) instance koneksi yang terpisah. Apakah saya mengerti Anda benar? "Loop dalam kode Anda hanyalah contoh yang terlalu disederhanakan, bukan?
Akan lebih baik untuk membuat
PreparedStatement
sekali saja, dan menggunakannya kembali berulang kali dalam loop.Dalam situasi di mana itu tidak mungkin (karena terlalu rumit aliran program), masih bermanfaat untuk menggunakan
PreparedStatement
, bahkan jika Anda menggunakannya hanya sekali, karena pekerjaan sisi server (parsing SQL dan caching eksekusi rencana), masih akan dikurangi.Untuk mengatasi situasi di mana Anda ingin menggunakan kembali sisi Java
PreparedStatement
, beberapa driver JDBC (seperti Oracle) memiliki fitur caching: Jika Anda membuatPreparedStatement
SQL yang sama pada koneksi yang sama, itu akan memberi Anda yang sama (cache ) contoh.Tentang multi-threading: Saya rasa koneksi JDBC tidak dapat digunakan bersama di beberapa utas (misalnya, digunakan secara bersamaan oleh beberapa utas). Setiap utas harus mendapatkan koneksi sendiri dari kolam, menggunakannya, dan mengembalikannya ke kolam lagi.
sumber