Memakai c3p0 Di Hibernate JPA


Sebelum sebuah aplikasi dapat memberikan query SQL, ia harus melakukan koneksi ke server database terlebih dahulu. Setelah query SQL selesai diberikan, aplikasi biasanya menutup koneksi database. Bila hal ini (membuat dan menutup koneksi) dilakukan terus menerus setiap kali melakukan query SQL, maka akan berdampak pada kinerja aplikasi. Hal ini akan semakin terasa bila lokasi client dan server di komputer yang berbeda yang diakses melalui jaringan.

Solusi untuk masalah seperti ini adalah dengan memakai JDBC connection pool. Cara paling naif adalah hanya membuat sebuah koneksi database dan memakai ulang koneksi ini sampai aplikasi ditutup. Akan tetapi solusi ini bisa menimbulkan masalah baru, misalnya bila terjadi gangguan jaringan pada koneksi database, maka koneksi menjadi tidak valid. Koneksi yang tidak valid tersebut tidak dapat lagi dipakai untuk mengerjakan SQL. Hal ini membuat aplikasi harus ditutup agar koneksi baru kembali dibuat.

Oleh sebab itu, daripada membuat sendiri, saya bisa memakai JDBC connection pool open-source yang sudah teruji seperti c3p0 dan Apache DBCP. Connection pool yang baik akan berusaha sebisa mungkin memakai koneksi yang sudah ada dan membuat koneksi hanya baru bila dibutuhkan. Pada tulisan ini, saya akan menggunakan c3p0 pada aplikasi yang memakai Hibernate JPA. Saya dapat menemukan artifak JAR untuk c3p0 di http://mvnrepository.com/artifact/com.mchange/c3p0. Karena saya memakai Griffon, saya bisa menambahkan baris berikut ini pada BuildConfig.groovy:

griffon.project.dependency.resolution = {
    ...
    repositories {
        griffonHome()
        mavenLocal()
        mavenCentral()
    }
    dependencies {
        runtime 'com.mchange:c3p0:0.9.2.1'
        runtime 'org.hibernate:hibernate-c3p0:4.3.6.Final'
        ...
    }
}

Dependency ke com.mchange:c3p0 akan menambah JAR milik c3p0. Sementara itu, org.hibernate:hibernate-c3p0 dibutuhkan untuk memakai c3p0 pada Hibernate JPA.

Langkah terakhir untuk mengaktifkan c3p0 adalah menambah konfigurasi seperti berikut ini pada persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence ...>
  <persistence-unit ...>
    ...
    <properties>
      ...
      <property name="hibernate.connection.provider_class" value="org.hibernate.c3p0.internal.C3P0ConnectionProvider" />
      ...
    </properties>
  </persistence-unit>
</persistence>

Setelah konfigurasi di atas diberikan, Hibernate akan memakai c3p0 connection pool dengan nilai konfigurasi default. Tidak ada kode program yang perlu diberikan untuk memakai c3p0, tapi ada banyak konfigurasi yang bisa diatur. Informasi lebih lanjut mengenai konfigurasi c3p0 dapat dibaca di http://www.mchange.com/projects/c3p0/. Saya dapat memberikan nilai konfigurasi yang ada langsung pada persistence.xml atau membuat sebuah file baru dengan nama c3p0.properties. Sebagai latihan, saya akan membuat file c3p0.properties di folder resources atau root dari folder source yang isinya seperti berikut ini:

c3p0.minPoolSize = 3
c3p0.maxPoolSize = 5
c3p0.initialPoolSize = 3
c3p0.acquireRetryAttempts = 10
c3p0.testConnectionOnCheckout = true

Pada konfigurasi di atas, pada saat aplikasi dijalankan, akan ada 3 koneksi database yang dibuat (nilai dari c3p0.initialPoolSize). Ketiga koneksi ini akan dipakai ulang sebisa mungkin. Koneksi yang dibuat ini tidak harus aktif dan dipakai. Umumnya database akan mempertahankan koneksi yang tidak ditutup oleh aplikasi (baik disengaja atau tidak) atau yang berada dalam keadaan tidur. Sebagai contoh, pada MySQL Server, saya bisa memberikan perintah SQL seperti:

SHOW VARIABLES LIKE 'wait_timeout';

untuk melihat seberapa lama server MySQL akan menunggu aktifitas jaringan sebelum menutup sebuah koneksi dari client di komputer berbeda. Secara default, nilai ini adalah 28800 detik atau 8 jam.

Bila terjadi gangguan jaringan atau masalah lain yang menyebabkan aplikasi tidak dapat terhubung ke server database, maka tanpa connection pool, aplikasi akan mendapatkan kesalahan (exception). Akan tetapi, bila memakai c3p0, aplikasi akan berusaha mencoba mendapatkan koneksi baru ke server database selama berkali-kali. Saya dapat mengatur berapa kali upaya mencoba mendapatkan koneksi dengan mengisi nilai c3p0.acquireRetryAttempts. Sebagai contoh, pada konfigurasi saya, hanya setelah 10 kali upaya mendapatkan koneksi gagal baru aplikasi memperoleh kesalahan JDBC (exception).

Sebuah koneksi dalam pool bisa saja menjadi rusak atau stale. Sebagai contoh, bila server database di-restart, maka seluruh koneksi sebenarnya telah ditutup. Akan tetapi, pada sisi client, koneksi masih tertampung di pool. Seluruh koneksi yang ada di pool kini sudah tidak valid lagi dan c3p0 harusnya membuat koneksi baru. Saya bisa mengatur agar c3p0 mendeteksi koneksi yang tidak valid pada saat koneksi tersebut akan dipakai. Caranya adalah dengan memberi nilai true pada c3p0.testConnectionOnCheckout. Alternatif lainnya adalah membuat c3p0 secara periodik memeriksa koneksi yang tidak valid di pool dengan memberi nilai true pada c3p0.testConnectionOnCheckin dan nilai periode pemeriksaan dalam detik pada c3p0.idleConnectionTestPeriod.

JDBC 4 mendukung isValid() pada Connection untuk menentukan apakah koneksi tersebut masih valid atau tidak. Bila driver JDBC yang dipakai mendukung JDBC 4 (misalnya, MySQL Connector/J di versi 5.1 ke atas), maka c3p0 akan memakai isValid(). Cara ini adalah yang paling cepat. Pada driver JDBC lama, sebuah SQL dapat diberikan sebagai nilai untuk c3p0.preferredTestQuery. SQL ini akan dipakai untuk menguji apakah koneksi masih aktif atau tidak. Bila query SQL tersebut gagal, maka koneksi dianggap tidak aktif.

Fasilitas menarik lainnya dari c3p0 adalah ia mendukung JMX sehingga saya bisa menggunakan JConsole untuk melihat dan melakukan perubahan konfigurasi pada sebuah aplikasi yang sedang dijalankan tanpa harus menutup dan men-compile ulang kode program untuk aplikasi tersebut. Program JConsole dapat dijumpai di lokasi %JDK_HOME%/bin/jconsole.exe. Setelah dijalankan, saya memilih virtual machine untuk aplikasi. Setelah itu, saya dapat melihat statistik dan melakukan perubahan konfigurasi c3p0 seperti yang terlihat pada gambar berikut ini:

Melakukan Administrasi c3p0 Melalui JMX

Melakukan Administrasi c3p0 Melalui JMX

Beberapa operasi membutuhkan username dan password yang isinya harus sesuai dengan yang diberikan pada saat membuat koneksi JDBC.

Perihal Solid Snake
I'm nothing...

Apa komentar Anda?

Please log in using one of these methods to post your comment:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

%d blogger menyukai ini: