Search

Senin, 04 Juli 2011

Transaction

Transaction Database

Dalam database management system (dbms) ada yang di sebut transaction. Transaction dalam dbms ini bertujuan untuk menggabungkan beberapa statement perubahan kedalam database menjadi dianggap satu kesatuan. Dilakukan semuanya atau tidak sama sekali (all or nothing) sehingga tidak terjadi ketidakkonsistenan data.. Transaksi mempunyai 2 fungsi utama:
1. Menyediakan reliabilitas, artinya jika terjadi kesalahan pada salah satu statement maka seluruh perubahan akan digagalkan. Sehingga data yang tersimpan benar benar reliable(dapat diandalkan).
2. Melakukan isolasi, artinya satu transaksi harus di proses satu persatu. Sehingga tidak ada kemungkinan 2 program mengakses atau bahkan mengubah data sekaligus.
Dalam transaksi ada 4 komponen utama, yaitu Atomicity, Consistency, Isolation and Durability yang biasa di singkat dengan ACID. Berikut penjelasannya:
Atomicity
Adalah suatu aturan dimana perubahan dilakukan secara keseluruhan atau tidak sama sekali. Sehingga jika di tengah transaksi terjadi kegagalan maka seruluruh perubahan akan di batalkan dan di kembalikan kekondisi semula. Kegagalan disini bisa terjadi karena aplikasi, system, database dsb.
Contoh (Ambil kasus transfer di suatu bank dari rek A ke rek B dengan nilai transfer 1000):
Maka stepnya adalah sebagai berikut:
1. Cek saldo A apakah mencukupi, jika mencukupi maka lanjut ke step ke-2. Jika tidak maka transaksi selesai dan tidak ada perubahan.
2. Kurangi saldo A sebesar 1000
3. Tambahkan saldo B sebesar 1000
Seluruh step diatas harus digabungkan sehingga apabila setelah step ke-2 terjadi kesalahan maka seluruh perubahan transaksi harus di batalkan. Setelah transaksi berhasil maka akan di lakukan commit.
Consistency
Menunjukkan konsistensi data yang ada setelah terjadi transaksi. Misalnya pada contoh kasus sebelumya, jika saldo A = 2000 dan saldo B = 500, maka setelah transaksi saldo A = 1000 dan saldo B = 1500. Nah beberapa hal yang biasanya ditangani oleh dbms adalah mengenai integrity constraint. Sedangkan jika berupa hasil perhitungan bisa di lakukan oleh aplikasi.
Isolation
Pada prinsip isolation, data yang sedang di lakukan perubahan tidak boleh diakses oleh lebih dari satu operasi. Harus hanya satu operasi yang melakukan perubahan ini. Sehingga jika ada operasi lain yang akan merubah maka harus menunggu sampai transaksi yang berlangsung selesai.
Misal ada 2 transaksi transfer antara rek A, dan rek B yang terjadi secara bersamaan:
T1 : Transfer A->B senilai 500
• Kurangi saldo A 500
• Tambah saldo B 500
T2 : Transfer B->A senilai 1000
• Kurangi saldo B 1000
• Tambah saldo A 1000
Nah bayangkan jika transaksi tersebut terjadi secara bersamaan dan di proses tanpa isolasi sehingga akan menjadi:
• Kurangi saldo A 500
• Tambah saldo B 500
• Kurangi saldo B 1000
• Tambah saldo A 1000
Jika terjadi kegagalan pada T1, maka data akan tidak konsisten sebab pada T2 sudah mengganti menambahkan saldo pada B. Demikian pentingnya isolasi, sehingga data tidak akan bisa di akses secara bersamaan oleh lebih dari satu operasi.
Durability
Kemampuan DBMS untuk menyimpan data transaksi yang terjadi. Sehingga jika terjadi kegagalan, DBMS menjamin bahwa data transaksi yang telah tersimpan tidak akan hilang. Banyak DBMS yang menuliskan log untuk suatu transaksi yang dapat digunakan ketika terjadi error pada hardware maupun software.
Salah satu poin penting dalam database transaction adalah atomic, yaitu beberapa perintah dianggap sebagai satu kesatuan. Kalau satu gagal, yang lain harus dibatalkan.
Ini adalah fundamental dari pemrograman dengan menggunakan database relasional.
Pada kasus apa perlu transaction? Ya pada semua kasus yang perlu atomic. Contohnya : header detail. Sekali insert, 1 header dan beberapa detail. Kalo pada waktu insert detail gagal, ya headernya harus diundo, kalo ngga ada header yang gantung tanpa detail sehingga datanya juga jadi salah.
Sekarang balik saya tanya, aplikasi apa yang gak pake skema header detail? Kecuali aplikasi prakarya tugas sekolah, aplikasi bisnis pasti pake header detail.
Itu masalah atomicity. Kemudian ada masalah isolation. Isolation ini artinya, transaction yang belum dicommit, tidak akan bisa dibaca oleh session lain. Contohnya gini, kita terima order 1000 item. Tentunya butuh waktu untuk menginsert 1000 record, misalnya butuh waktu 2 detik. Di dunia prosesor, 2 detik itu lama sekali, dan banyak hal bisa terjadi dalam rentang waktu tersebut. Nah, akan terjadi musibah, kalo kita ternyata ada fitur untuk menghitung jumlah order, katakan saja querynya seperti ini.

select sum(nilai) from t_order where tanggal = '2011-02-02'
yang berjalan di tengah-tengah proses insert tadi, misalnya pada waktu baru terinsert 53 order saja. Query hitung ini dijalankan oleh user lain. Suatu hal yang sangat umum terjadi, aplikasi diakses beberapa user berbarengan.
Query ini akan menghasilkan nilai yang salah, karena 1000 order itu belum tentu sukses diinsert. Misalnya pada record ke 143 terjadi mati lampu, hardisk penuh, komputer hang, browser ketutup, laptop kesiram kopi, usernya menekan tombol cancel, validasi stok produk tidak cukup, atau whatever kejadian remeh-temeh yang umum terjadi dalam kehidupan sehari-hari, tentu akan terjadi kekacauan. Karena tidak atomic, maka kita tidak tau sudah berapa record yang terinsert, sehingga menyulitkan proses recovery. Order mana yang harus diinsert ulang, dan order mana yang sudah masuk? Karena tidak ada isolation, maka user yang menjalankan perhitungan order akan mendapat hasil yang tidak sahih kebenarannya.
Seandainya saja kita menggunakan transaction dengan benar, maka pada waktu terjadi sesuatu pada waktu proses insert tadi, maka posisi database akan dikembalikan ke posisi sebelum insert dilakukan. Karena posisi sebelum insert kita tahu dengan pasti, maka recovery gampang. Insert ulang saja 1000 order tadi tanpa kecuali. Sederhana dan mudah.
Jadi kalo ada di sini yang bilang bikin aplikasi bisnis tanpa transaction, maka itu adalah nonsense. Tidak peduli kalo sampe saat ini jalan lancar, maka itu hanyalah kebetulan belaka, dan kita tidak mau selamanya mengandalkan keberuntungan kan? Kalau sampai saat ini berjalan lancar, ya mungkin aplikasinya cuma dipakai 1 concurrent user saja dan itupun jarang-jarang pake.
Nah, jadi transaction itu adalah fitur fundamental yang harus digunakan, sama seperti kalo kita keluar rumah ya harus pake celana. Di daerah lain sana orang kemana2 cuma pake koteka, dan saya tidak mau berdebat dengan mereka urusan celana. Jadi kalo masih ada yang bersikukuh bikin aplikasi bisnis gak pake transaction, ya silahkan, saya tidak mau berdebat urusan ini. Percuma berdebat sama orang yang gak pake celana ;p
Selanjutnya, sebetulnya apa benar transaction itu memberatkan aplikasi? Hmm … ini sebetulnya hanyalah mitos belaka. Yang mau mendebat silahkan sajikan benchmark antara non-transactional dan transactional. Kalo selisih performance cuma 100%, artinya kalo non-transactional cuma 2 kali lebih lemot, saya mendingan upgrade hardware daripada mengorbankan data integrity untuk gain performance yang tidak seberapa ini.
Jadi, apa kita tidak boleh pakai MyISAM ? Tentu ada waktu dan tempatnya. Data2 read only seperti misalnya tabel kategori, master produk, bolehlah pake MyISAM. Tapi kalo sudah data header detail, ya harus InnoDB dan harus menggunakan transaction supaya atomic.
Setelah kita menggunakan InnoDB, sebetulnya kita tidak bisa non-transactional. Kalo kita tidak begin dan commit secara explisit, sebenarnya untuk tiap SQL statement, itu dianggap satu transaction. Sehingga SQL seperti ini :
update table harga set nilai = nilai + 1000;
Sebetulnya akan dijalankan seperti ini ;
begin;
update table harga set nilai = nilai + 1000;
commit;
Ini namanya fitur autocommit. Di MySQL defaultnya dienable.
Dengan adanya autocommit ini, justru kita akan lebih lemot kalo tidak menggunakan transaction secara benar. Contoh, insert 100 data produk. Kalo tanpa begin dan commit explisit, berarti ada 100 begin dan ada 100 commit, artinya 100 kali menjalankan transaction. Akan lebih efisien kalo kita lakukan explisit, seperti ini :
begin;
insert into table produk (kode) values ('P-001');
... ulangi 99 kali lagi ..
commit;
Cara di atas hanya akan membutuhkan satu transaction saja. Jauh lebih efisien.
Baiklah, ada beberapa pesan moral di artikel ini
1. Header detail harus dioperasikan secara atomic
2. Operasi yang belum selesai, tidak boleh dilihat session lain, sehingga untuk aplikasi multiuser, pasti butuh isolation
3. Karena aplikasi bisnis umumnya multiuser, dan pasti punya skema header-detail, maka pasti harusmenggunakan transaction
4. Masalah performance di transaction umumnya mitos belaka, dan walaupun ada, tidak sebanding dengan mengabaikan integritas data
5. Jangan lupa pakai celana kalau keluar rumah
Pembaca setia blog saya tentu paham bahwa biasanya saya memberikan anjuran dengan kata-kata sebaiknya, tergantung situasi, dan istilah-istilah yang relatif. Tapi di artikel ini, banyak kata-kata pasti, harus, dan sejenisnya. Ini karena masalah transaction ini berkaitan dengan integritas data. Aplikasi yang kita buat haruslah bisa dipercaya untuk menghasilkan perhitungan yang benar. Tanpa menjaga integritas data dengan transaction, mustahil perhitungan yang benar bisa didapatkan.

Tidak ada komentar:

Posting Komentar