Database Transaction

Artikel ini saya tulis berdasarkan diskusi tentang transaction di milis id-mysql. Awalnya sederhana, ada yang tanya begini,

halo rekan2 dba & developer

mysql-innodb kan punya fasilitas transaction yang seperti oracle/postgres tuh.
mau nanya, dalam implementasi real di aplikasi,
contoh bussiness process/use case apa aja yang menggunakan transaction?
kemudian contoh kasus rollbacknya gimana?

Tadinya saya kurang semangat menjawab, karena asumsi saya, ini pertanyaan mendasar, dan pastilah banyak yang bisa menjawab secara benar dan tidak menyesatkan. Tapi apa lacur, saya membaca pertanyaan lanjutan seperti ini.

Ada yang pernah punya pengalaman pake software accounting tanpa feature
transaction?

Dan jawabannya ternyata sangat mengerikan.

yup, pernah.. 3 aplikasi sudah berjalan berbeda2 kasus accounting nya..
dan tidak menggunakan feature transaction…
skrng sedang garap accounting lainnya untuk perusahan dagang, dan
sudah direncakan tanpa feature transaction.

yg aplikasi 1 dr taun 2002, aplikasi 2 dr taun 2004, aplikasi 3 dr jan 2010.
oya, ada jg aplikasi lain di sekitar taun 2005-2009, beberapa masih
dipakai, beberapa tdk dipakai karena masalah internal mereka.
dan selama ini aplikasi yg telah dipakai masih ok2 saja pak.

menurut singkat saya, jika peng-handle php nya sudah cukup
menanggulangi masalah transaksi data, tidak harus menggunakan feature
transaction pada database nya.
karena pd umumnya yg sudah berjalan, kebutuhan inti ada pada
pencarian, input, edit, delete dengan kecepatan yg tinggi dan diakses
oleh beberapa user, dan juga optimize database, dengan begitu menurut
hemat saya, saya lebih condong menggunakan MyIsam yg tdk menggunakan
feature transaction yg sedikit memberatkan proses data.

oya, untuk case mengharuskan memakai feature transaction itu misalnya
pada kasus:
- jika pada aplikasi tidak meng-handle apabila ada data transaksi yg
dihapus/update/input yg mengharuskan ada link data yg juga ikut
terupdate/terhapus/terinput

untuk yg sudah menggunakan feature transaction, silahkan saya juga
menunggu tanggapan dan pengalamannya.

What the @#$!
Ini kalo meminjam istilah MUI, harus dibimbing untuk kembali ke jalan yang benar, tapi tidak boleh anarkis :D

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.

Lebih lanjut tentang masalah-masalah yang bisa terjadi, bisa lihat di Wikipedia.

14 Responses to “Database Transaction”

  1. Wah, mudah2an banyak yang tercerahkan setelah membaca artikel ini :-D

  2. Setuju, kalau masalah adalah performance, maka lebih baik meningkatkan hardware daripada mengorbankan integritas ata … tulisan yang bagus, cocok untuk saya referensikan ke teman2x yang kontra dengan transaction :)

  3. Terima kasih untuk pencerahannya. Jadi ‘ngerti deh.

  4. Muhamad Kuncoro Says:
    February 16, 2011 at 5:21 pm

    wah artikelnya pas Mas, ketika mo njelasin fungsi commit pada rekan..:D makasih banyak

  5. Hmm.. Bukan bermaksud untuk bilang “no transaction database”, tapi mungkin yang pake MYSQL bukan orang-orang dengan nilai project di atas belasan juta. Mungkin mereka berpikir masalah “efesiensi dana”. AFAIK, banyak project di Indonesia khususnya di daerah-daerah yang gak mau ngeluarin budget di atas 7 digit.. Malah ada yang ratusan ribu rupiah aja. Dan si konsultannya mikir, daripada gak makan mending di ambil lah project itu. No offense..

    Btw, masalah “Data2 read only seperti misalnya tabel kategori, master produk, bolehlah pake MyISAM”. Bahkan mungkin data master produk dan kategori pun berelasi, dalam kasus product punya kategori. Ketika insert kategori dan produk bersamaan, ini butuh transaction juga kan..? Atau produk biasanya jadi reference ketika input header detail di dalam suatu order. Disini juga kita butuh ngisolasi si produk supaya gak di utak-atik ketika orang input order. Atau saya juga salah?

  6. Kalo seandainya database transaction itu ‘mahal’, mungkin saya tidak akan bersikeras seperti ini.

    Kenyataannya kan database transaction itu fitur standar yang gratis di semua database relasional. Tanpa perlu beli addon atau plugin tambahan, pasti sudah ada.

    Cara pakainya pun tidak sulit. Di banyak framework sudah diotomasi.

    Jadi, dengan murah dan mudah ini, kenapa lagi kita gak pakai.

    Urusan performance, itu mitos belaka. Coba aja cari di internet artikel yang menyatakan bahwa dia gak pake transaction karena lemot. Pasti dihajar sama komentator.

    Mengenai produk dan kategori pakai MyISAM, itu ya tergantung situasi. Saya bilang boleh bukan berarti saya menggunakannya.
    Saya pribadi gak mau repot, pake aja InnoDB untuk semua tabel. Gak ribet mikir mana yang MyISAM mana yang InnoDB.

  7. Artikel bagus pak Endy,

    Tetapi ada juga kok aplikasi enterprise CRM yang diakuisisi oleh perusahaan database terkenal. ternyata tidak mempunyai transaction di component databasenya jika ada custom development didalamnya. saya sudah bertanya ke expertnya ternyata aplikasi enterprise tersebut tidak ada model transaction.Tidak abis pikir apakah arsitekturnya waktu itu tertidur sampai lupa harus design transaction model?

    di SAP meski dicustom (menggunakan ABAP) masih kenal transaction, istilahnya kalau tidak salah logical unit of work.

  8. wahhhhh…….
    artikelnya keren mas Endy….terima kasih banyak mas…
    blh nanya sdkit mas Endy…kn seperti penjelasan sebelumnya kl di SQL it Begin….Commitnya gk kelihatan…cara nampilinnya gmna?maaf pertanyaan mendasar..heheheh

  9. muantabs mas endy..intinya kita harus pakai celana! ehehehehe

  10. salam mas,
    Yang nanya pertama itu saya. dimana saya ingin tahu implementasi transaksi di real-world.
    akhirnya dibuat juga artikelnya.
    thanks,
    penjelasannya bagus.
    hehehe

  11. hello world :)

    artikelnya benar2 bagus sekali pak :D
    saya akhirnya mudeng mengenai transaksi di sql,
    trimakasih banyak pak artikelnya,
    sangat membantu ^.^

    semoga barokah……

  12. bagus sekali artikelnya pak, saya yang sudah cerah aja makin dapat pencerahan dengan membaca artikel ini, hehehehehe ;p

  13. sy adalah newbie dalam penggunaan oracle 10g.
    pengetahuan tentang oracle adalah zero (kosong) kerana sebelum ini sy bekerja di bidang TECHNICAL dan sekarang sy mendapat pekerjaan baru dalam programmer. Ia begitu kontra dgn kemahiran saya. blh kah saudara/i yg bijak sana membantu saya untuk memahirkan diri dalam penggunaan oracle db ini.

    kerjasama dr anda semua amatlah di hargai.

    Terima kasih.

  14. saya harap kalian smua dapat membantu sy.

    Terima kasih.

Leave a Reply