Kode Anda pada dasarnya benar. Pengecualian yang muncul saat terjadi dead lock adalah SQLException
. Pengecualian getSQLState()
metode memberikan pengembalian kode kesalahan yang memberikan informasi tambahan
tentang kesalahan yang sebenarnya.
Anda juga harus menunggu beberapa saat di antara percobaan, agar tidak terlalu banyak memuat server Anda.
Seperti yang Anda tebak dengan cerdik, tetapkan jumlah upaya maksimum, atau Anda mungkin berakhir dalam lingkaran tak terbatas.
Kode terakhir bisa terlihat seperti ini:
boolean oops;
int retries = 5;
Connection c = null;
Statement s = null;
ResultSet rs = null;
do
{
oops = false;
c = null;
s = null;
rs = null;
try
{
c = openConnection();
s = c.createStatement();
rs = s.executeQuery("SELECT stuff FROM mytable");
fiddleWith(rs);
}
catch (SQLException sqlex)
{
oops = true;
switch(sqlex.getErrorCode()())
{
case MysqlErrorNumbers.ER_LOCK_DEADLOCK:
// deadlock or lock-wait time-out occured
break;
...
}
Thread.sleep(1000); // short delay before retry
}
finally
{
if (rs != null) try {
rs.close();
} catch (SQLException e) {
// some error handler here
}
if (s != null) try {
s.close();
} catch (SQLException e) {
// some error handler here
}
if (c != null) try {
c.close();
} catch (SQLException e) {
// some error handler here
}
}
}
while (oops == true && retries-- > 0);
Jelas kode di atas adalah sub optimal. Anda mungkin ingin membedakan kesalahan yang terjadi pada waktu koneksi dan kesalahan pada waktu eksekusi. Anda juga dapat mendeteksi bahwa setelah beberapa kesalahan, hanya ada sedikit harapan bahwa upaya lain akan berhasil (mis. kredensial yang salah atau kesalahan sintaks SQL).
Anda mengajukan banyak pertanyaan, tetapi saya akan mencoba menjawab semuanya:
Ya, lihat di atas:SQLException
's adalah satu-satunya, dengan informasi lebih lanjut disediakan oleh getErrorCode()
atau getSQLState()
.
Sebuah SQLException
dapat dilempar oleh hampir semua metode dari semua kelas dari java.sql
paket.
Ya, lihat di atas.
Jelas Anda tidak boleh membuat ulang PreparedStatement
antara dua pertanyaan. Anda hanya perlu menyetel nilai baru ke parameter Anda sebelum memanggil executeQuery()
lagi. Tentu saja jika Anda perlu menjalankan kueri lain, maka PreparedStatement
baru diperlukan.
A (baru) ResultSet
objek dikembalikan oleh Statement.executeQuery()
, yang mewakili hasil kueri. Anda tidak pernah membuat objek seperti itu sendiri. Idealnya Anda akan memanggil ResultSet.close()
sesegera mungkin untuk melepaskan memori.
Saya sangat menyarankan Anda untuk mengikuti bab kedua dari tutorial ini ("Memproses Pernyataan SQL").