Tuesday, December 21, 2010

Save Point Oh Save Point (bukan check point)

Wihartoyo     Tuesday, December 21, 2010    
Kemarin, sore hari, dah mau pulang, gak jadi. Ada sedikit tantangan yang muncul dari masalah salah seorang kawan di kantor. Masalahnya adalah; beliau punya stored procedure yang dijalankan pada Sybase Adaptive Server Enterprise (Sybase ASE), tetapi ada 'ketidak-konsisten-an' ketika Stored Procedure itu dijalankan.  Nah, mungkin, karena dianggap sebagai salah seorang yang tahu mengenai seluk beluk Sybase ASE, atau sekedar cari temen diskusi, temen ini ngajak diskusi sambil membuka source dari stored procedure beliau punya. Phh...., pening juga aku melihat source script yang bukan tumpahan pemikiranku.

Sambil membuka-buka source beliau mulai bercerita bahwa stored procedure nya yang telah beliau set chained mode nya menjadi anymode (bisa chained, bisa juga unchained) dengan harapan sifat procedure dalam menangani variable bisa lebih flexible ternyata masih menyisakan misteri yang agak (ya memang sekedar agak, karena aku tahu kapasitas beliau) sulit untuk dipecahkan.
Jadi begini, beliau punya dua stored procedure.  Satu stored procedure dipanggil oleh stored procedure yang lainnya. Gambarannya bisa dilihat pada frame berikut:

  1. declare proc...
  2. .
  3. .
  4. begin
  5.   set chained on
  6. end
  7. .
  8. .
  9. .
  10. begin transaction alltran
  11. begin
  12.   call my_sp (@status)-->sp ini ada transaksi insert, tidak mengandug commit di dalamnya
  13.   if @status = -1
  14.    begin
  15.     rollback
  16.     raise error
  17.     return(1) -->return error
  18.    end
  19. end

  20. insert ...
  21. if @@rowcount > 0 and status != -1 -->commit di sini.
  22. begin
  23.   commit tran
  24.   return(0)
  25. end
  26. else
  27. begin
  28.   rollback
  29.   return(1)
  30. end

Dan beliau cerita juga bahwa beberapa test yang beliau lakukan terhadap stored procedurenya, memberikan pesan kesalahan bahwa seakan dalam stored procedure beliau ada rollback/commit yang tidak didahului dengan begin. Padahal, menurut beliau dan sesuai penglihatanku juga, semua sudah setangkup. Gak ada yang nyelonong sendirian.  Hasil test memberikan pesan bahwa commit/rollback tidak didahului oleh save point. Dan lebih jauh lagi, ternyata, setelah menjalankan/call my_sp dan secara keseluruhan stored_procedure seharusnya rollback, ternyata insert yang dijalankan oleh my_sp tetap commit.

Save point, aku yang lebih banyak berkutat dengan masalah replikasi, awalnya, nangkepnya save point itu sama dengan check point (setelah masalah terselesaikan, dalam hati, kemudian, aku tertawa ngikik, karena sok tahu menyamakan save point sama check point).  Ya aku bilang, apa hubungannya dengan stored procedure.  Tambah lagi, example save point yang didapat juga bunyinya 'save transaction precentagesave'.  Vvvh.., masa harus ngukur persentasi proses yang mau disimpan di log sih?

Setelah puter otak kanan kiri dan ngomong ini ngomong itu dalam diskusi, akhirnya intuisiku berjalan.  Save point, hmm... pastinya ini bukan masalah replikasi.  Tetapi masalah session transaksi. Hmmm terus aku usul bagaimana kalau ada perubahan begini:

  1. declare proc...
  2. .
  3. .
  4. begin
  5.   set chained on
  6. end
  7. .
  8. .
  9. .
  10. begin transaction alltran
  11. begin
  12. save transaction  currTran
  13.   call my_sp (@status)-->sp ini ada transaksi insert, tidak mengandug commit di dalamnya
  14.   if @status = -1
  15.    begin
  16.     rollback currTran
  17.     raise error
  18.     return(1) -->return error
  19.    end
  20. end

  21. insert ...
  22. if @@rowcount > 0 and status != -1 ->commit di sini.
  23. begin
  24.   commit tran
  25.   release currTran
  26.   return(0)
  27. end
  28. else
  29. begin
  30.   rollback tran
  31.   release currTran
  32.   return(1)
  33. end

Setelah ditambahkan beberapa baris seperti di atas, akhirnya masalah terpecahkan.  Eksekusi nested stored procedure my_sp seperti di dalam contoh sudah bisa terkontrol sepenuhnya dengan menerapkan save point yang bukan check point.  Kesimpulannya, karena tidak menerapkan save point maka nested procedure yang secara anatominya memakai satu blok tersendiri, maka, bila aplikasi menerapkan autocommit dalam mengeksekusi stored procedure induknya, nested stored procedure secara otonom akan menginsert dan commit tanpa mengabaikan rule yang didisain dalam mengeksekusi stored procedure tersebut.  Oleh karena proses telah di commit, maka proses rollback akan memberikan pesan kesalahan.  Untuk itulah maka diperlukan save point yang akan memegang status transaksi.
Itu aja. He he he...

Recommended