Dikatakan sebagai kebiasaan yang baik untuk menutup semua sumber daya JDBC setelah penggunaan. Tetapi jika saya memiliki kode berikut, apakah perlu untuk menutup Resultset dan Pernyataan?
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = // Retrieve connection
stmt = conn.prepareStatement(// Some SQL);
rs = stmt.executeQuery();
} catch(Exception e) {
// Error Handling
} finally {
try { if (rs != null) rs.close(); } catch (Exception e) {};
try { if (stmt != null) stmt.close(); } catch (Exception e) {};
try { if (conn != null) conn.close(); } catch (Exception e) {};
}
Pertanyaannya adalah apakah penutupan koneksi berfungsi atau apakah ada sumber daya yang digunakan.
Jawaban:
Apa yang telah Anda lakukan adalah latihan yang sempurna dan sangat baik.
Alasan saya mengatakan ini adalah praktik yang baik ... Misalnya, jika karena alasan tertentu Anda menggunakan tipe penyatuan basis data "primitif" dan Anda menelepon
connection.close()
, koneksi akan dikembalikan ke kolam danResultSet
/Statement
tidak akan pernah ditutup dan kemudian Anda akan mengalami banyak masalah baru yang berbeda!Jadi Anda tidak bisa selalu mengandalkan
connection.close()
pembersihan.Saya harap ini membantu :)
sumber
Java 1.7 membuat hidup kita lebih mudah berkat pernyataan coba-dengan-sumber daya .
Sintaks ini cukup singkat dan elegan. Dan
connection
memang akan ditutup bahkan ketika yangstatement
tidak bisa dibuat.sumber
;
)Dari javadocs :
Namun, javadocs tidak begitu jelas tentang apakah
Statement
danResultSet
ditutup ketika Anda menutup yang mendasarinyaConnection
. Mereka hanya menyatakan bahwa menutup Koneksi:Menurut pendapat saya, selalu ditutup secara eksplisit
ResultSets
,Statements
danConnections
ketika Anda selesai dengan mereka sebagai implementasiclose
dapat bervariasi antara driver database.Anda dapat menghemat banyak kode boiler-plate dengan menggunakan metode seperti
closeQuietly
pada DBUtils dari Apache.sumber
Saya sekarang menggunakan Oracle dengan Java. Di sini sudut pandang saya:
Anda harus menutup
ResultSet
danStatement
secara eksplisit karena Oracle memiliki masalah sebelumnya dengan menjaga kursor tetap terbuka bahkan setelah menutup koneksi. Jika Anda tidak menutupResultSet
(kursor) itu akan menimbulkan kesalahan seperti kursor terbuka maksimum terlampaui .Saya pikir Anda mungkin mengalami masalah yang sama dengan database lain yang Anda gunakan.
Ini adalah tutorial Tutup ResultSet ketika selesai :
sumber
Jika Anda menginginkan kode yang lebih ringkas, saya sarankan menggunakan Apache Commons DbUtils . Pada kasus ini:
sumber
Metode yang benar dan aman untuk menutup sumber daya yang terkait dengan JDBC ini (diambil dari Cara Menutup Sumber Daya JDBC dengan Benar - Setiap Saat ):
sumber
Tidak masalah apakah
Connection
dapat dikumpulkan atau tidak. Bahkan koneksi yang dapat dikumpulkan harus dibersihkan sebelum kembali ke kolam."Bersihkan" biasanya berarti menutup hasil & mengembalikan semua transaksi yang tertunda tetapi tidak menutup koneksi. Jika tidak, pooling kehilangan akal sehatnya.
sumber
Tidak, Anda tidak perlu menutup apa pun TETAPI koneksi. Per spesifikasi JDBC yang menutup objek yang lebih tinggi akan secara otomatis menutup objek yang lebih rendah. Penutup
Connection
akan menutupStatement
koneksi apa pun yang telah dibuat. Menutup apa punStatement
akan menutup semuaResultSet
yang dibuat oleh ituStatement
. Tidak masalah apakahConnection
dapat dikumpulkan atau tidak. Bahkan koneksi yang dapat dikumpulkan harus dibersihkan sebelum kembali ke kolam.Tentu saja Anda mungkin memiliki loop panjang bersarang pada
Connection
pembuatan banyak pernyataan, lalu menutupnya adalah tepat. Saya hampir tidak pernah menutupResultSet
, sepertinya berlebihan ketika menutupStatement
atauConnection
AKAN menutupnya.sumber
Saya membuat Metode berikut untuk membuat One Liner yang dapat digunakan kembali:
Saya menggunakan Kode ini dalam Kelas induk yang diwarisi ke semua kelas saya yang mengirim DB Queries. Saya dapat menggunakan Oneliner pada semua Pertanyaan, bahkan jika saya tidak memiliki resultSet. Metode ini menangani penutupan ResultSet, Pernyataan, Koneksi dalam urutan yang benar. Inilah yang akhirnya tampak seperti blok saya.
sumber
Sejauh yang saya ingat, di JDBC saat ini, Resultset dan pernyataan mengimplementasikan antarmuka AutoCloseable. Itu berarti mereka ditutup secara otomatis saat dihancurkan atau keluar dari ruang lingkup.
sumber
close
tersebut dipanggil pada akhir pernyataan coba-dengan-sumber daya. Lihat docs.oracle.com/javase/tutorial/essential/exceptions/… dan docs.oracle.com/javase/8/docs/api/java/lang/AutoCloseable.html .Beberapa fungsi kenyamanan:
sumber
Dengan Java 6 form saya pikir lebih baik untuk memeriksa apakah sudah ditutup atau tidak sebelum ditutup (misalnya jika beberapa pooler koneksi membatalkan koneksi di utas lainnya) - misalnya beberapa masalah jaringan - pernyataan dan status resultset dapat ditutup. (tidak sering terjadi, tapi saya punya masalah dengan Oracle dan DBCP). Pola saya untuk itu (dalam sintaks Java yang lebih lama) adalah:
Secara teori itu tidak 100% sempurna karena antara memeriksa keadaan dekat dan penutupan itu sendiri ada sedikit ruang untuk perubahan keadaan. Dalam kasus terburuk Anda akan mendapatkan peringatan lama. - tetapi lebih kecil dari kemungkinan perubahan negara dalam permintaan jangka panjang. Kami menggunakan pola ini dalam produksi dengan muatan "rata-rata" (150 pengguna simultan) dan kami tidak punya masalah dengan itu - jadi jangan pernah melihat pesan peringatan itu.
sumber
isClosed()
tes, karena menutup semua yang sudah ditutup ini adalah larangan. Yang menghilangkan masalah jendela waktu. Yang juga akan dihilangkan dengan membuat variabelConnection, Statement
, danResultSet
lokal.