Ini adalah salah satu tantangan kami secara teknis berkaitan dengan database. Suatu saat kami mencatatkan header transaksi dengan autogenerated number yang merupakan fitur natif dari database. Field bertipe big integer ini menjadi Primary Key untuk relasi ke tabel detail atau tabel lain yang berelasi. Semua baik-baik saja.
Keadaan berubah saat ada beberapa divisi memerlukan penomeran yang lebih mudah dibaca (readable). Beberapa divisi ini menginginkan penggunaan prefix untuk membedakan dengan transaksi dari divisi lain. Misalnya divisi penjualan umum menggunakan prefix “FU”, penjualan rawat inap dengan prefix “FI” dan penjualan rawat jalan dengan “FJ”. Ditambahkan lagi prefix berdasarkan waktu transaksi sehingga formatnya menjadi “FJ1208xxxxx” untuk penjualan rawat jalan.
Dengan penomeran model begini user bisa dengan cepat mengidentifikasi transaksi tersebut dari divisi mana dan terjadi pada tahun dan bulan berapa.
Beberapa divisi lain juga menginginkan hal yang sama, misalnya divisi Laboratorium dan Radiologi. Sedangkan divisi lain tidak memerlukan fitur penomeran readable ini. Jadi divisi lain tetap menggunakan Primary Key. Sedangkan beberapa divisi menggunakan TrxID.
Masalah ini diselesaikan secara teknis dengan menambahkan 1 field pendamping Primary Key, yaitu field “TrxID” yang diharapkan dapat menjadi Primary Key ke-2 yang harus bisa unik tetapi untuk kebanyakan departemen berisi kosong (NULL). Jadi harus unik tetapi bisa kosong (tidak unik).
Request ini diselesaikan secara softwariah. Software akan mencari nomer terakhir TrxID sesuai dengan prefix yang dimaksud kemudian menambahkan 1. Nampaknya masalah terselesaikan.
Tapi ternyata tidak!
Pada suatu waktu ada 2 user yang melakukan transaksi secara bersamaan dan mendapatkan nomer TrxID yang sama. Dan karena field ini bukan Primary Key atau Unique Index yang sesungguhnya dan tidak ada constraint secara native, maka kedua transaksi ini bisa disimpan dengan nomer TrxID yang sama.
Ini menjadi masalah besar. Walau pun detail transaksi tetap mengacu kepada Primary Key yang sesungguhnya, tapi user menjadi bingung dengan keberadaan 2 TrxID yang sama! Padahal konsistensi relasi header dan detail transaksi tetap terjaga dengan penggunaan Primary Key yang sesungguhnya. Sebenarnya 2 transaksi ini tetap 2 transaksi yang berbeda.
Pernah ada yang mengalami hal yang sama? Bagaimana pemecahan untuk mencegah hal ini? Yang jelas field TrxID ini bisa berisi kosong jika divisi lain tidak membutuhkan penomeran yang readable. Jadi field ini pun tidak bisa dibikin unique secara native di database.
Ternyata tidak sesederhana itu!
ayo semangat kak~ 😀
Terima kasih semangatnya…
aku tunggu hasilnya aja deh mas hehehe malas mikir
Hiks… bantuin dooonk…
Ditambahkan lagi prefix berdasarkan waktu transaksi sehingga formatnya menjadi “FJ1208xxxxx”
====
xxxxx dibelakang itu rumusnya apa mas? kalau mau di bikin lebih susah untuk sama, isi aja dengan timestamp sampai ke milidetik saat di generate, jadi lebih panjang memang, tapi akan lebih “unique”
xxxxx = nomer urut 5 digit. Misalnya: FJ120800001, FJ120800002, dst…
Wah kalau sampai ke timestamp bisa pusing semua, hehehe…
Tapi tetap bisa terjadi jika 2 user input bareng sampe ke detik yg sama, hiks…
Terima kasih masukannya.
hmm kalau mau lebih simple lagi, sebelum insert, lakukan logic pengecekan key itu.. pada saat key yang akan di insertkan ternyata sudah di commit ke database(artinya sudah dipakai oleh orang lain) ambil key terbesar terakhir di database, tambahkan satu lalu insert he he he.. memang jadi membuat lebih lama prosesnya… nanti kalau kepikiran cara lain lagi, saya tulis disini
Algoritma yg sekarang sih begini:
1. Cek nomer terakhir transaksi (sesuai prefix)
2. Tambahkan 1
3. Simpan transaksi ke DB dgn nomer tsb
Kalau sebelum simpan ngecek lagi nomer tsb, kayaknya bakal memakan resources server. Karena jika ternyata nomer tsb sudah ada, maka akan kembali ke langkah no. 1. Bisa terjadi rekursif sih.
Ide lain sih dgn mekanisme “reserved number”. Ada sebuah tabel yg menyimpan nomer terakhir sesuai prefix. Setiap tambah transaksi akan me-reserve nomer baru. Tetapi berpotensi user reserved nomer yg sama juga. Kecuali tabel tersebut di-lock.
Ditunggu ide lain ya, Mas. Terima kasih
eh jadi kepikiran lagi, apakah key ini ditampilkan di form pada saat sebelum insert? pertanyaan mendasar sih sebelum ke solusi harusnya.. karena kalau di hidden akan lebih mudah, dan ditampilkan saat sudah masuk ke db… kalau di tampilkan sebelum di insert, dan di hapal sama user.. baru perlu trik lain lagi 🙂
sorry lagi kumat iseng untuk alpro nya 🙂 jadi perlu tahu case detail nya untuk bisa solve suatu problem 🙂
Ditampilkan. Saat membuat transaksi baru isinya “AUTO”. Saat sudah disimpan (baik header mau pun detailnya) barulah berisi nomer transaksi yg sebenarnya.
Ada ide?
berarti jawabannya harusnya TIdak ditampilkan, karena yang muncul isinya AUTO 🙂 setelah disimpan baru tampil he he he, ..
nanti kalau lagi agak lowong saya carikan idenya.. ide pake table reserved tadi oke juga, hanya saja triggernya itu harusnya button create transaction, jadi pada saat user klik create transaction, langsung insertkan satu nomer dan pakai nomer itu. Kenapa button create transaction? karena secara system timestamp sampai MILIdetik, harusnya setiap transaksi pasti unik 🙂
Betul, Mas.
Kalau pakai tabel reserved harus lock table supaya tidak double. Sayangnya user kami banyak & transaksinya banyak juga sehingga sulit jika menggunakan lock table.
Kalau saat create transaction sdh membuat nomer transaksi, kemudian user membatalkannya, maka banyak nomer transaksi yg bolong2 dan kesannya lompat2, hiks…
Baik mas, saya tunggu ide2nya. Terima kasih ya