implementasi concurrency control dalam database …
TRANSCRIPT
IMPLEMENTASI CONCURRENCY CONTROL DALAM
DATABASE ORACLE 10G UNTUK MULTIUSER MENGGUNAKAN ORACLE PL/SQL
(Contoh Kasus : Aplikasi Berupa Simulasi Untuk Teller Bank
dalam Mengakses Rekening Nasabah Bank)
SKRIPSI
Ditujukan Untuk Memenuhi Salah Satu Syarat
Memperoleh Gelar Sarjana Teknik Jurusan Teknik Informatika
Disusun Oleh :
Shinta Grace Octovia
015314090
JURUSAN TEKNIK INFORMATIKA FAKULTAS SAINS & TEKNOLOGI UNIVERSITAS SANATA DHARMA
YOGYAKARTA 2007
IMPLEMENTATION OF CONCURRENCY CONTROL IN
DATABASE ORACLE 10G FOR MULTIUSER USING ORACLE PL/SQL
(Case Study : Aplication in Simulation Form Used By Bank Teller
In Order To Access The Customer Bank Account)
SKRIPSI
Proposed To Fulfil One Of The Requirements
To Obtain Bachelor Degree In Information Technology
By :
Shinta Grace Octovia
015314090
INFORMATION TECHNOLOGY FACULTY OF SCIENCE & TECHNOLOGY
SANATA DHARMA UNIVERSITY YOGYAKARTA
2007
i
iv
PERNYATAAN
Dengan ini saya sebagai penulis tugas akhir menyatakan dengan
sesungguhnya bahwa skripsi yang saya tulis ini tidak memuat karya atau bagian
karya orang lain, kecuali pemikiran, metode atau hasil penelitian orang lain yang
diambil disebutkan dengan jelas sebagai acuan.
Yogyakarta, September 2007
Penulis
Shinta Grace Octovia
v
HALAMAN PERSEMBAHAN
Karya ini kupersembahkan untuk :
“The King Of Majesty”, Tuhanku Yesus Kristus, karena atas
anugerahNyalah karya ini dapat dimulai serta diakhiri dengan indah.
Segala hal yang terbaik hanya pantas diberikan untukNya…
,
Bapak dan Mama, atas kuatnya dukungan cinta lewat doa, semangat dan
harapan yang tidak pernah pudar, untukku...
,
Babang, Tinus, Uda, InangUda, Bou, Amangboru, serta semua sepupu &
seluruh keluarga besar, yang senantiasa memberikan dorongan semangat
serta dukungan doa, untukku…
,
“My BIG family in Christ”, yang telah mendukungku dalam meraih segala
hal yang terbaik yang telah DIA tentukan sejak semula…
,
Seluruh sahabat & teman, yang telah menemaniku dan turut memberikan
kehangatan pada hari-hari yang telah kujalani…
vi
HALAMAN MOTTO
“ Trust in the LORD with all your heart
and lean not on your own understanding;
in all your ways acknowledge Him,
and He will make your paths straight”
Proverbs 3 : 5-6
Ia membuat segala sesuatu indah pada waktunya..
( Pengkhotbah 3 :11a)
“Aku melayangkan mataku ke gunung-gunung;
dari manakah akan datang pertolonganku?
Pertolonganku ialah dari TUHAN,
yang menjadikan langit dan bumi ”
- Mazmur 121 : 1-2 –
vii
ABSTRAKSI
Transaksi dalam sebuah aplikasi yang digunakan oleh single user
menjamin keakuratan data dalam database yang diupdate pada suatu waktu.
Namun lain halnya pada transaksi yang terjadi pada aplikasi yang digunakan oleh
beberapa user/multiuser. Harus ada managemen transaksi berupa concurrency
control untuk mengelola transaksi-transaksi yang terjadi. Hal ini menjadi penting
mengingat transaksi yang terjadi pada aplikasi yang digunakan oleh multiuser
tersebut dapat saja terjadi secara bersama-sama dalam suatu waktu dan dapat
melakukan intervensi secara simultan pada suatu item data. Jika transaksi-
transaksi tersebut tidak dikelola dengan baik oleh database, maka akan dapat
mengakibatkan data yang tidak valid serta tidak konsisten.
Concurrency control dalam managemen transaksi ini akan
diimplementasikan dalam contoh kasus berupa aplikasi simulasi untuk teller Bank
dalam mengakses rekening nasabah Bank. Setiap teller akan diberi hak untuk
mengakses database rekening nasabah. Namun pada suatu waktu ada
kemungkinan rekening seorang nasabah di-update secara bersama-sama oleh lebih
dari satu teller. Implementasi concurrency control yang baik untuk multiuser pada
setiap transaksi dalam database dapat menjamin data dalam keadaan yang valid
dan konsisten.
viii
ABSTRACT
The transaction of an application using for single user guarantee the
accuracy data on database when updated on a same periodic time. However, in
the same case, it could be different with the transaction which used by multiusers.
Management transaction such as concurrency control is needed to manage the
transactions occured. Concurrency control is an important matter because the
transactions occured on the application which used by the multiusers could be
happen concurrently at the same time and could be execute as simultant
intervension on a data item. When the transactions are not manage in a good
management transaction such as concurrency control on the database, it caused
the data result not valid and not consistent.
Concurrency control on this transaction management case will be
implemeted on the case study of application in simulation form used by bank
teller in order to access the customer bank account. Every teller has rightful
authority to access the database account of the costumer. However, at the same
periodic time there probably updating occured to the account simultantly by more
than one teller. A good implementation of concurrency control for multiuser at the
transaction when accessing item data on the database could guarrantee the data
in a valid and consistent condition.
ix
KATA PENGANTAR
Puji dan syukur penulis panjatkan kepada Tuhan Yang Maha Kuasa
yang telah melimpahkan berkat-Nya sehingga penulis dapat menyelesaikan
Laporan Tugas Akhir ini. Penulisan tugas akhir ini ditujukan untuk memenuhi
salah satu syarat memperoleh gelar Sarjana Teknik Jurusan Teknik Informatika.
Terselesaikannya penulisan tugas akhir ini tidak lepas dari peran serta
beberapa pihak, baik secara langsung maupun secara tidak langsung. Oleh karena
itu, penulis ingin menyampaikan terima kasih kepada pihak-pihak yang telah ikut
membantu dalam penulisan tugas akhir ini, baik dalam memberikan bimbingan,
petunjuk, kerjasama, kritikan, maupun saran antara lain kepada:
1. Bapak JB. Budi Darmawan, S.T., M.Sc., selaku Dosen Pembimbing, yang
telah banyak membantu terutama dalam memberikan bimbingan, dukungan,
dan perhatian, sehingga penulis dapat menyelesaikan laporan tugas akhir ini.
Terima kasih banyak atas semuanya, Pak.
2. Ibu Agnes Maria Polina, S.Kom., M.Sc., selaku Ketua Jurusan Teknik
Informatika Universitas Sanata Dharma.
3. Bapak Alb. Agung Hadhiatma, S.T., M.T dan Bapak H. Agung Hernawan,
S.T, selaku Dosen Penguji TA.
4. Seluruh Dosen Universitas Sanata Dharma, khususnya Dosen yang mengajar
di Teknik Informatika, yang telah memberikan dan mengajarkan banyak ilmu
kepada penulis.
x
5. Bapak dan Mama yang telah mendukungku sepenuhnya. Trimakasih untuk
segenap keberadaan diri kalian untukku... I’m so blessed to have you as my
parents.
6. My lovely Bro’: Babang & Tinus. Trimakasih untuk dorongan semangat terus
menerus lewat sms, hehe! ☺ Always prays, that God give you all the best in
your life...
7. Uda&Inanguda, Bou&Amangboru, Ica dan segenap keluarga besar Hutasoit.
Mauliate...
8. My BIG.. BIG.. family in Christ : TQ for all the joy & happiness!!
- Buat AKTBku : Herma, Yuli, Geo, Fani. TQ tuk dukungan dalam bentuk
sms, doa, dll... I praise God to have u all as my lovely sista...
- Kak Fona & Bang Be, TQ a lot 4 da everything..
- Fanya, Ardi, Pras, Reni, Fani Hohoho!! Always “FACING OUR
GIANT!!!” ☺ SEMANGAT!!!
- Adik-adik TPSY semuanya! TQ dah jadi “pasukan doa”ku ☺
- Rekan-rekan P’tas, semuanya!! TQ!!
9. Vrysca & Lia, TQ untuk segenap bentuk pertolongan yang tepat pada
waktunya... Hehe ☺
10. Teman-teman kost 99999 : Diana, Maria, July, Welly, Jean, Vivi, Olive.
Makasih banget dah nemenin hari-hariku dengan banyak tawa.
11. Teman-teman TI’01 : Nia (TQ for our sharing ‘bout anything), Nita, Vivi,
Christin, Desni, Andri, Tio, Andi, Sigit, Anand, Dami, Wahyu (& Anton),
xi
Narko & Teman-teman kelompok proyek RPL : Yoseph, Manu, Vini (yang
dah jauh dimato).
12. Untuk Rina, Gini, Lia, Mahendra, Ani, Fani, Mindy, yang terus menerus
memberikan semangat kepada penulis untuk menyelesaikan TA ini.
13. Matakuliah : KALKULUS... TQ dah ngajarin arti “Perjuangan tak henti”
menghadapi setiap keterbatasan diri di “sekolah kehidupan” ini.
14. Dan seluruh pihak yang telah ikut ambil bagian dalam penyelesaian laporan
tugas akhir ini yang tidak dapat penulis sebutkan satu-persatu.
Seperti kata pepatah, “Tak ada gading yang tak retak”, maka penulis
menyadari segala keterbatasan dalam menyelesaikan laporan tugas akhir ini. Oleh
karena itu, penulis ingin menyampaikan mohon maaf apabila terdapat kesalahan
dan kekurangan. Untuk itu, penulis mengharapkan kritik dan saran yang
membangun dari seluruh pihak yang membutuhkan laporan tugas akhir ini.
Semoga laporan tugas akhir ini dapat memberikan manfaat bagi siapa
saja yang membutuhkannya. Atas segala perhatiannya dan kerjasamanya, penulis
ucapkan terima kasih.
Yogyakarta, September 2007
Penulis,
Shinta Grace Octovia
xii
DAFTAR ISI
Halaman Judul........................................................................................................
Halaman Persetujuan..................................................................................................
Halaman Pengesahan........................................................................................
Halaman Pernyataan.........................................................................................
Halaman Persembahan..............................................................................................
Halaman Motto.................................................................................................
Abstraksi...........................................................................................................
Abstract................................................................................................................
Kata Pengantar....................................................................................................
Daftar Isi...........................................................................................................
Daftar Gambar...................................................................................................
Daftar Tabel.......................................................................................................
BAB I Pendahuluan ……………………………………………………………..
1.1 Latar Belakang Masalah………………………………….....................
1.2 Rumusan Masalah..…………………………………………………….
1.3 Batasan Masalah.……………………………….……………………….
1.4 Tujuan Penelitian..…………………………………………..................
1.5 Metodologi Penelitian .………………………………………................
1.6 Sistematika Penelitian…………………………………….....................
BAB II Landasan Teori………………………………………………………….
2.1 Pembahasan tentang Managemen Transaksi ………………………….
i
ii
iii
iv
v
vi
vii
viii
ix
xii
xvi
xviii
1
1
2
2
3
3
4
5
5
xiii
2.2 Pembahasan tentang Concurrency Control…………………………….
2.2.1 Kebutuhan Concurrency Control…………………………………
2.2.2 Masalah yang Muncul dalam Akses Bersama dan Hasil yang
Diharapkan……………………………………………………….
2.3 Concurrency Control dalam Oracle........................................................
2.3.1 Multiversion Read Consistency………………………………..
2.3.2 Macam-macam Level Isolasi Oracle..........................................
2.3.3 Deteksi Deadlock……………...................................................
2.4 Database Oracle 10g..............................................................................
2.5 Pemrograman Database dengan Oracle PL/SQL................................
2.5.1 Mengambil Data di PL/SQL........................................................
2.5.2 Memasukkan Data Menggunakan PL/SQL.................................
2.5.3 Meng-update dan Menghapus Data..............................................
2.5.4 Konvensi Nama……....................................................................
2.5.5 Mengontrol Transaksi……........................................................
2.6 Aplikasi Database C#.NET...................................................................
2.6.1 Mengenal C#.NET......................................................................
2.6.2 Teknologi ADO.NET.................................................................
2.6.2.1 Oracle Connection……………………………………..
2.6.2.2 Oracle Data Adapter dan Data Set………......................
2.6.2.3 Oracle Command…........................................................
2.6.3 Membuat Koneksi Database……………………………………
7 7
8
11
12
15
17
17
19
21
21
22
22
23
24
24
24
26
26
27
27
28 BAB III Analisa Permaslahan Dan Perancangan Sistem………………………
xiv
3.1 Analisa Permasalahan…………………………………………………
3.1.1 Permasalahan-permasalahan yang Timbul jika Tidak Terdapat
Penanganan Concurrency Control……………………………..
3.1.2 Sistem yang Dikembangkan……………………………………
3.1.3 Requirement Analysis..................................................................
3.1.4 Data Modelling…………………………………………………
3.2 Perancangan Sistem ………………………………………………….
3.2.1 Perancangan Database…………………………………………
BAB IV Implementasi Sistem……….………………………………………….
4.1 Karakteristik Sistem………………………………………………….
4.2 Kebutuhan Sistem……………………………………………………
4.3 Setting Koneksi Oracle 10g XE ke C#.Net………………………….
4.4 Pembuatan Antar Muka Pemakai (User Interface)..............................
4.4.1 User Interface Form Utama.............................................................
4.4.2 User Interface Form Login Teller Bank.....................................
4.4.3 User Interface Menu Utama.......................................................
4.4.4 User Interface Form Transaksi Penarikan Tunai........................
4.4.5 User Interface Form Transaksi Penyetoran Tunai.......................
28
29
31
33
34
37
37
39
39
40
40
43
43
44
47
52
58
64
71
74
76
78
4.4.6 User Interface Form Transaksi Transfer Saldo..........................
4.4.7 User Interface Form Transaksi Total Saldo................................
4.4.8 User Interface Form Hasil Transaksi Penarikan Tunai..............
4.4.9 User Interface Form Hasil Transaksi Penyetoran Tunai............
4.4.10 User Interface Form Hasil Transaksi Transfer Saldo...............
xv
4.4.11 User Interface Form Hasil Transaksi Total Saldo Nasabah......
BAB V Analisa Hasil.........................................................................................
5.1 Pengujian Aplikasi ...............................................................................
5.1.1 Pengujian Aplikasi Tanpa Menggunakan Concrrency
Control.........................................................................................
5.1.1.1 Pengujian Terhadap Masalah Hilangnya Data yang
Diubah ( Lost of Update)....................................................
5.1.1.2 Pengujian Terhadap Masalah Analisa yang Tidak
Konsisten ( The Inconsistent Analysis Problem)..............
5.1.2 Pengujian Aplikasi Dengan Menggunakan
Concurrency Control....................................................................
5.1.2.1 Pengujian Terhadap Masalah Hilangnya Data yang
Diubah ( Lost of Update)..................................................
5.1.2.2 Pengujian Terhadap Masalah Analisa yang Tidak
Konsisten ( The Inconsistent Analysis Problem)...............
5.2 Kelebihan dan Kekurangan Sistem..........................................................
5.3.1 Kelebihan Sistem ..........................................................................
5.3.2 Kekurangan Sistem......................................................................
BAB VI Penutup ..................................................................................................
6.1 Kesimpulan ............................................................................................
6.2 Saran ......................................................................................................
DAFTAR PUSTAKA............................................................................................
81
83
83
83
84
89
94
96
101
108
108
109
110
110
110
111
xvi
DAFTAR GAMBAR
Tabel Keterangan Halaman
Gambar 2.1 Diagram Transsisi Transaksi 6 Gambar 3.1 Use Case Diagaram 33 Gambar 3.2 ER-Diagram 34 Gambar 3.3 Context Diagram 35 Gambar 3.4 Diagram Berjenjang 35 Gambar 3.5 Data Flow Diagram 36 Gambar 3.6 Tabel Relasi Transaksi Pada Teller Bank 37 Gambar 4.1 User Interface Form Utama 43 Gambar 4.2 Form Login Teller Bank Untuk Aplikasi Tanpa
Concurrency Control 44
Gambar 4.3
Form Login Teller Bank Untuk Aplikasi Dengan Concurrency Control
45
Gambar 4.4
Form Menu Utama Untuk Aplikasi Tanpa Concurrency Control
47
Gambar 4.5
Form Menu Utama Untuk Aplikasi Dengan Concurrency Control
48
Gambar 4.6
Form Transaksi Penarikan Tunai Untuk Aplikasi Tanpa Concurrency Control
52
Gambar 4.7
Form Transaksi Penarikan Tunai Untuk Aplikasi Dengan Concurrency Control
53
Gambar 4.8
Form Transaksi Penyetoran Tunai Untuk Aplikasi Tanpa Concurrency Control
58
Gambar 4.9
Form Transaksi Penyetoran Tunai Untuk Aplikasi Dengan Concurrency Control
59
Gambar 4.10
Form Transaksi Transfer Saldo Untuk Aplikasi Tanpa Concurrency Control
64
Gambar 4.11
Form Transaksi Transfer Saldo Untuk Aplikasi Dengan Concurrency Control
65
Gambar 4.12
Form Transaksi Total Saldo Untuk Aplikasi Tanpa Concurrency Control
71
Gambar 4.13
Form Transaksi Total Saldo Untuk Aplikasi Dengan Concurrency Control
71
Gambar 4.14
Form Hasil Transaksi Penarikan Tunai Untuk Aplikasi Tanpa Concurrency Control
74
Gambar 4.15
Form Hasil Transaksi Penarikan Tunai Untuk Aplikasi Dengan Concurrency Control
75
Gambar 4.16
Form Hasil Transaksi Penyetoran Tunai Untuk Aplikasi Tanpa Concurrency Control
76
Gambar 4.17
Form Hasil Transaksi Penyetoran Tunai Untuk Aplikasi Dengan Concurrency Control
77
xvii
Gambar 4.18
Form Hasil Transaksi Transfer Saldo Tanpa Concurrency Control
78
Gambar 4.19 Form Hasil Transaksi Transfer Saldo Dengan Concurrency Control
79
Gambar 4.20
Form Hasil Transaksi Total Saldo Tanpa Concurrency Control
81
Gambar 4.21
Form Hasil Transaksi Total Saldo Dengan Concurrency Control
81
Gambar 5.1
Simulasi 2 Transaksi Berjalan Bersamaan untuk Aplikasi Tanpa Concurrency Control – Hilangnya Data Yang Diubah
85
Gambar 5.2 Simulasi Hasil Transaksi 2 Transaksi Berjalan Bersamaan untuk Aplikasi Tanpa Concurrency Control – Hilangnya Data yang Diubah
85
Gambar 5.3
Simulasi 2 Transaksi Berjalan Bersamaan untuk Aplikasi Tanpa Concurrency Control – Masalah Analisa yang Tidak Konsistent
90
Gambar 5.4
Simulasi Hasil Transaksi 2 Transaksi Berjalan Bersamaan untuk Aplikasi Tanpa Concurrency Control – Masalah Analisa yang Tidak Konsisten
91
Gambar 5.5
Simulasi 2 Transaksi Berjalan Bersamaan untuk Aplikasi Dengan Concurrency Control – Terhadap Masalah Hilangnya Data Yang Diubah
96
Gambar 5.6
Simulasi Hasil Transaksi 2 Transaksi Berjalan Bersamaan untuk Aplikasi Dengan Concurrency Control – Terhadap Masalah Hilangnya Data yang Diubah
97
Gambar 5.7
Simulasi 2 Transaksi Berjalan Bersamaan untuk Aplikasi Dengan Concurrency Control – Masalah Analisa yang Tidak Konsistent
102
Gambar 5.8
Simulasi Hasil Transaksi 2 Transaksi Berjalan Bersamaan untuk Aplikasi Dengan Concurrency Control – Masalah Analisa yang Tidak Konsisten
103
xviii
DAFTAR TABEL
Tabel Keterangan Halaman
Tabel 2.1 Level Isolasi Transaksi Menurut SQL92 10 Tabel 2.2 Berbagai Tipe Data PL/SQL 19 Tabel 2.3 Berbagai Operator PL/SQL 20 Tabel 2.4 Namespace Pada ADO.NET 25 Tabel 3.1 Ilustrasi Masalah Hilangnya Data Yang Diubah 29 Tabel 3.2 Ilustrasi Masalah Analisa Yang Tidak Konsisten 30 Tabel 3.3 Struktur Tabel Nasabah 38 Tabel 3.4 Struktur Tabel Jenis Transaksi 38 Tabel 3.5 Struktur Tabel Transaksi 38 Tabel 3.6 Struktur Tabel Teller Bank 38 Tabel 5.1 Proses Yang Terjadi Pada Pengujian Aplikasi
Tanpa Menggunakan Concurrency Control – Terhadap Masalah Hilangnya Data Yang Diubah
88
Tabel 5.2 Proses Yang Terjadi Pada Pengujian Aplikasi Tanpa Menggunakan Concurrency Control – Terhadap Masalah Analisa Yang Tidak Konsisten
94
Tabel 5.3 Proses Yang Terjadi Pada Pengujian Aplikasi Dengan Menggunakan Concurrency Control – Terhadap Hilangnya Data Yang Diubah
100
Tabel 5.4 Proses Yang Terjadi Pada Pengujian Aplikasi Dengan Menggunakan Concurrency Control – Terhadap Masalah Analisa Yang Tidak Konsisten
107
x
1
BAB I
PENDAHULUAN
1.1 Latar Belakang Masalah
Masalah yang timbul dalam sebuah aplikasi database untuk multiuser yaitu
bagaimana database tersebut dapat menjamin data yang dipresentasikan kepada
user merupakan data yang konsisten, walaupun terdapat beberapa transaksi yang
mengeksekusi data tersebut dalam waktu yang hampir bersamaan. Akses bersama
pada suatu aplikasi database untuk multiuser relatif lebih mudah jika semua user
hanya membaca data, sehingga tidak ada yang saling melakukan interfensi satu
dengan yang lainnya terhadap suatu data. Namun lain halnya jika pada suatu saat
yang hampir bersamaan terdapat dua atau lebih user yang mengeksekusi suatu
data dalam database secara simultan atau paling sedikit terdapat satu user yang
melakukan update, padahal user lain yang mengeksekusi data tersebut belum
selesai dengan eksekusinya, hal ini mengakibatkan data yang diberikan kepada
user dalam keadaan tidak konsisten dan tidak valid. Diperlukan sebuah
penanganan berupa concurrency control untuk melindungi data dari akses secara
simultan oleh multiuser.
Salah satu contoh implementasi penanganan concurrency control yang
baik dalam dunia nyata adalah aplikasi yang digunakan oleh Teller Bank dalam
mengakses rekening Nasabah Bank. Pada saat yang hampir bersamaan mungkin
saja terdapat beberapa Teller yang berada dilain tempat sedang mengeksekusi
2
suatu data dari database rekening nasabah milik seorang Nasabah Bank.
Permasalahan yang timbul yaitu bagaimana data dalam database yang diberikan
kepada user tetap konsisten dan merupakan hasil yang sebenarnya, walaupun
terdapat beberapa interfensi/perubahan yang dilakukan oleh beberapa Teller Bank
terhadap suatu data rekening milik seorang Nasabah dalam waktu yang hampir
bersamaan dan secara simultan.
1.2 Rumusan Masalah
Dari latar belakang masalah diatas terdapat beberapa rumusan masalah
yaitu:
1. Bagaimana mengimplementasikan concurrency control dalam database
Oracle 10g untuk multiuser dengan menggunakan Oracle PL/SQL?
2. Bagaimana mengintegrasikan implementasi concurrency control dalam
database Oracle 10g tersebut dalam sebuah aplikasi untuk Teller Bank
dalam mengakses rekening Nasabah Bank?
1.3 Batasan Masalah
Dalam mengimplementasikan concurrency control dalam database Oracle
10g untuk multiuser dengan menggunakan Oracle PL/SQL, contoh kasus aplikasi
berupa simulasi untuk Teller Bank dalam mengakses rekening Nasabah Bank,
dilakukan batasan sebagai berikut:
1. Database yang digunakan diasumsikan database terpusat (centralized
database).
3
2. Aplikasi hanya berupa simulasi, bukan program utuh yang dapat dipakai
oleh Teller Bank.
3. Tidak membahas jaringan komputer dan keamanannya.
1.4 Tujuan Penelitian
Mengimplementasikan concurrency control dalam database Oracle 10g
untuk multiuser dalam suatu aplikasi untuk end user berupa aplikasi simulasi
untuk Teller Bank dalam mengakses rekening Nasabah Bank.
1.5 Metodologi Penelitian
1. Studi pustaka tentang concurrency control dalam Oracle
2. Menganalisa permasalahan-permasalahan yang dapat terjadi dalam
aplikasi untuk multiuser dan merumuskan sistem yang akan dibangun
untuk dapat mengatasi permasalahan-permasalahan yang ada.
3. Merancang sistem yang akan dibangun meliputi perancangan database,
perancangan user interface secara terinci guna memberikan gambaran
umum mengenai sistem yang akan dibangun.
4. Mengimplementasikan rancangan aplikasi untuk Teller Bank dengan
implementasi concurrency control didalamnya..
4
1.6 Sistematika Penelitian
Sistematika penelitian skripsi secara garis besar meliputi:
BAB I. PENDAHULUAN
Bab ini berisi tentang Latar Belakang Masalah, Rumusan Masalah, Batasan
Masalah, Tujuan Penelitian, Metodologi Penelitian, Sistematika Penulisan.
BAB II. LANDASAN TEORI
Bab ini membahas landasan teori yang menjelaskan tentang Transaction
Management, Concurrency control, Concurrency control dalam Oracle, Database
Oracle 10g, Pemrograman Database dengan Oracle PL/SQL, dan Aplikasi untuk
User menggunakan C#.NET.
BAB III. ANALISA PERMASALAHAN DAN PERANCANGAN SISTEM
Bab ini membahas tentang analisa permasalahan, system yang dikembangkan,
perancangan database, dan perancangan user interface.
BAB IV. IMPLEMENTASI SISTEM
Bab ini membahas mengenai cara mengimplementasikan sistem yang dibuat
kedalam suatu program.
BAB V. ANALISA HASIL
Bab ini berisi analisa hasil dari imlementasi yang telah dibuat pada bab
sebelumnya.
BAB VI. KESIMPULAN DAN SARAN
Bab ini berisi kesimpulan dan saran.
5
BAB II
LANDASAN TEORI
2.1 Pembahasan tentang Management Transaksi
Transaksi adalah sebuah tindakan atau serangkaian tindakan, dilakukan
oleh single user atau program aplikasi, yang membaca atau mengubah isi dari
database.
Terdapat 4 hal dasar yang harus dimiliki semua transaksi, yaitu:
1. Atomicity. Sebuah transaksi adalah sebuah unit yang tidak dapat dibagi
lagi sehingga dapat melakukan seluruhnya atau tidak melakukan apapun.
Ini merupakan tanggung jawab dari subsystem recovery dari DBMS untuk
memastikan ke’atom’annya.
2. Consistency. Sebuah transaksi harus mentransformasikan satu keadaan
konsisten ke keadaan konsisten lainnya. Ini merupakan tanggung jawab
dari DBMS dan pengembang aplikasi untuk memastikan
kekonsistenannya.
3. Isolation. Transaksi secara bebas mengeksekusi yang lainnya. Dengan kata
lain, sebagian transaksi yang tidak lengkap akan mengakibatkan transaksi
yang lain menjadi tidak visible.Ini merupakan tanggung jawab dari
subsistem concurrency control untuk memastikan isolasi.
4. Durability. Setelah DBMS memberitahu pengguna bahwa transaksi telah
selesai dengan sukses, maka efeknya tetap bertahan bahkan jika system
mengalami crash sebelum semua perubahannya direfleksikan pada disk.
6
Ini merupakan tanggung jawab dari recovery subsystem untuk memastikan
durability.
Berikut Gambar2.1 merupakan digram transisi sebuah transaksi:
ACTIVE
PARTIALLY COMMITED
FAILED
COMMITTED
ABORTED
Begin transaction
abort
abort
End transaction
commit
Gambar 2.1 Diagram Transisi Transaksi
Dalam diagram transisi terdapat 5 keadaan yaitu:
1. ACTIVE (aktif)
2. PARTIALLY COMMITTED (sebagian dilaksanakan)
• terjadi setelah perintah terakhir dieksekusi
• pada saat ini, mungkin ditemukan transaksi melanggar
serializability atau melanggar integrity constraint, maka transaksi
harus dibatalkan. Transaksi demikian akan menuju FAILED
(keadaan gagal) dan harus dibatalkan
• jika transaksi sukses, beberapa update dapat disimpan secara aman
dan transaksi menuju ke keadaan COMMITTED.
7
3. COMMITTED (dilaksanakan)
4. FAILED (gagal)
• Terjadi jika transakasi tidak dapat dilaksanakan atau transaksi
dibatalkan pada saat ACTIVE (keadan aktif).
• Kondisi ini terjadi jika user membatalkan transaksi atau protocol
concurrency control membatalkan transaksi untuk memastikan
serialibility.
5. ABORTED (dibatalkan)
2.2 Pembahasan tentang Concurrency control
Concurrency control adalah proses pengelolaan operasi-operasi yang
berjalan bersamaan dalam database dengan tidak saling mengganggu satu sama
lain.
2.2.1. Kebutuhan Concurrency control
Kebutuhan concurrency control dalam managemen transaksi untuk
multiuser menjadi penting, mengingat sistem untuk multiuser memungkinkan
terjadinya akses bersama terhadap sebuah database. Akses bersama relatif mudah
jika seluruh user hanya membaca data, sehingga tidak ada yang melakukan
interfensi satu dengan lainnya. Akan tetapi, pada saat dua atau lebih user
mengakses database secara simultan dan paling sedikit satu user melakukan
update, maka akan terjadi interfensi yang dapat mengakibatkan
ketidakkonsistenan data pada database.
8
2.2.2. Masalah yang Muncul dalam Akses Bersama dan Hasil yang
Diharapkan
Terdapat beberapa masalah yang dapat terjadi yang disebabkan oleh akses
bersama oleh multiuser, yaitu:
1. Lost update problem (Masalah hilangnya data yang diupdate) : Sebuah
transakasi yang melakukan update, namun pada waktu interfal yang
bersamaan proses update tersebut ditimpa oleh transaksi lain.
2. Uncommitted dependency problem / dirty read (masalah kebergantungan
terhadap transaksi yang belum commit) : Sebuah transaksi dibiarkan untuk
melihat hasil transaksi intermediate (menengah) dari transaksi lain
sebelum dilakukan commit.
3. Inconsistent analysis problem (masalah analisa yang tidak konsisten) :
Sebuah transaksi membaca beberapa nilai dari database tetapi transaksi
kedua melakukan update terhadap sebagian dari beberapa nilai tersebut
selama proses eksekusi yang pertama.
4. Nonrepeatabel (atau fuzzy) read : Sebuah transaksi T membaca ulang data
item yang sebelumnya telah dibaca, sementara itu transaksi lain
melakukan modifikasi. Sehingga T akan menerima 2 buah nilai yang
berbeda untuk data item yang sama.
5. Phantom read : Transaksi T mengeksekusi sebuah query yang menerima
sekumpulan tuple dari sebuah relasi dengan predikat tertentu, melakukan
eksekusi ulang query pada waktu berikutnya tetapi menemukan kembali
sekumpulan tuple tambahan (phantom) yang disisipkan oleh transaksi lain
9
pada waktu tertentu. Untuk menangani masalah-masalah tersebut di atas,
diperlukan kontrol yang baik untuk menjamin konkurensi data dan
konsistensi data.
• Konkurensi data berarti bahwa banyak user yang dapat mengakses data
pada waktu yang bersamaan
• Konsistensi data berarti bahwa masing-masing user dapat melihat tampilan
data yang konsisten, termasuk jika terdapat perubahan yang dilakukan oleh
transaksi oleh user lain.
Kontrol yang baik dalam database terhadap eksekusi dari transaksi yang
dijalankan bersamaan yaitu jika transaksi yang dieksekusi bersama tersebut
menghasilkan hasil yang sama seperti jika transakasi-transaksi yang ada
dieksekusi secara serial (transaksi dijalankan sendiri-sendiri, tanpa ada sela,
menjamin konsistensi data). Hal ini dinamakan serializability.
Serializability, yang merupakan parameter keberhasilan dalam
concurrency control ini dapat dicapai dengan menggunakan macam-macam level
isolasi pada transaksi (transaction isolation levels), mekanisme locking pada data,
dan timestamp.
• Level Isolasi. Level isolasi mengontrol tingkat dimana transaksi tertentu
terbuka terhadap tindakan transaksi lain yang melakukan eksekusi secara
bersama. Dengan memilih satu dari empat kemungkinan pengaturan level
isolasi, user dapat memperoleh penanganan konkurensi yang peka
terhadap perubahan uncommitted oleh transaksi lain.
10
Plilihan level isolasi adalah READ UNCOMITTED, READ COMMITTED,
REPEATABEL READ dan SERIALIZABLE. Berikut merupakan tabel level isolasi
transaksi menurut ANSI/ISO SQL standard (SQL92) terhadap penanganan 3
masalah yang ditemukan dalam akses bersama.
Isolation level
Dirty Read Nonrepeatabel Read
Phantom Read
Read uncommitted
Mungkin Mungkin Mungkin
Read committed
Tidak Mungkin Mungkin
Repeatabel read
Tidak Tidak Mungkin
Serializable Tidak Tidak Tidak
Tabel 2.1 Level Isolasi Transaksi menurut SQL92
Level isolasi SERIALIZABLE secara umum merupakan yang paling aman
dan direkomendasikan untuk kebanyakan transaksi. Akan tetapi, beberapa
transaksi dapat bekerja dengan level isolasi lebih rendah, dan sejumlah kecil lock
yang diminta dapat memberikan konstribusi untuk meningkatkan performa
sistem.
• Metode Locking. Locking adalah sebuah prosedur yang digunakan untuk
melakukan kontrol pada akses bersama pada data. Pada saat satu transaksi
melakukan akses ke dalam database, sebuah lock akan menyebabkan
pelarangan akses ke dalam transaksi untuk mencegah hasil yang tidak
konsisten. Terdapat 2 jenis lock, yaitu Shared Lock, dan Executive Lock.
Jika sebuah transaksi memiliki shared lock pada sebuah data item, maka
transaksi tersebut dapat melakukan pembacaan terhadap sebuah item tetapi
11
tidak dapat melakukan update. Sedangkan jika sebuah transaksi yang
memiliki executive lock pada sebuah data item dapat melakukan
pembacaan maupun update item tersebut.
Namun dalam mekanisme locking, deadlock bisa terjadi. Deadlock adalah
sebuah jalan buntu yang merupakan hasil dari dua atau lebih transaksi
yang saling menuggu lock yang akan dilepaskan yang dipegang oleh
transaksi yang lainnya.
• Metode Timestamp. Timestamp adalah sebuah identitas yang unik yang
dibuat oleh DBMS yang menunjukkan adanya waktu starting yang relativ
dari sebuah transaksi. Metode ini agak berbeda dengan metode locking.
Tidak ada locking, dan tidak ada deadlock. Metode locking pada umunya
mencegah konflik dengan cara membuat transaksi yang lain menunggu.
Dalam metode timestamp, tidak ada menunggu, transaksi yang mengalami
konflik secara sederhana dirollback dan re-start.
2.3 Concurrency control dalam Oracle
Dalam menangani akses bersama, Oracle menggunakan protokol
Multiversion-Read Consistency yang menjamin user melihat data yang konsisten
yang diminta. Jika user lain mengubah data utama selama proses eksekusi query,
Oracle menjaga sebuah versi dari data sebagaimana adanya data tersebut pada
waktu query dimulai. Jika terdapat transaksi uncommitted dalam progress ketika
query dimulai, Oracle meyakinkan bahwa query ini tidak melihat perubahan yang
dibuat oleh transaksi ini. Oracle juga tidak menempatkan beberapa lock pada data
12
untuk operasi baca, yang artinya bahwa sebuah operasi baca tidak pernah
memblok sebuah operasi tulis.
2.3.1. Multiversion Read Consistency
Implementasi dari protocol Multiversion Read Consistency yang akan
dibahas meliputi Rollback segment, Serial Change Number (SCN) dan Lock.
• Rollback Segment, merupakan struktur dalam dalam database Oracle
digunakan untuk menyimpan informasi undo, ketika transaksi sedang
mengubah data dalam blok, Oracle pertama-tama menulis tampilan data
sebelumnya ke Rollback segment. Sebagai tambahan untuk mendukung
Multiversion Read Consistency, Rollback segment juga digunakan untuk
meng-undo sebuah transaksi. Oracle juga memelihara satu atau lebih
Redo-Logs, yang merekam semua transaksi yang terjadi dan digunakan
untuk me-recover database pada saat terjadi kesalahan dalam system.
• System Change Number (SCN), digunakan untuk memelihara order
kronologis yang tepat dalam operasi. Oracle menjaga SCN. SCN adalah
sebuah pemikiran tentang timestamp yang merekam order yang
didalamnya operasi terjadi. Oracle menyimpan SCN dalam Redo-Log
untuk me-redo transaksi dalam urutan yang tepat. Oracle menggunakan
SCN untuk menentukan versi sebuah item data yang mana harus
digunakan dalam sebuah transaksi. Oracle juga menggunakan SCN untuk
menentukan kapan untuk memberikan informasi dari Rollback Segment.
13
• Lock. Locking terjadi untuk semua statement SQL jadi seorang user tidak
pernah membutuhkan untuk me-lock resource-resource yang ada secara
tegas, meskipun Oracle menyediakan sebuah mekanisme untuk
memperbolehkan seorang user untuk mendapat lock secara manual atau
untuk mengubah default locking. Default mekanisme locking, men-lock
data pada level terendah dari yang dibatasi untuk menjamin integritas
ketika memperbolehkan tingkat tertinggi dari concurrency. Oracle
menyimpan informasi row-locking selama blok data actual dimana baris
tersebut disimpan. Sebagimana Oracle menyimpan lock pada baris selama
blok data, Oracle tidak pernah meningkatkan lock.
Oracle support tipe-tipe dari lock, meliputi:
• DDL locks- digunakan untuk memproteksi objek skema, seperti definisi
dari tabel dan view.
• DML locks – digunakan untuk memproteksi pokok data, sebagai contoh
lock pada tabel memprotek seluruh tabel dan baris lock pada baris.
• Internal locks- digunakan untuk memproteksi struktur data yang dishare.
• Internal latches- digunakan untuk memproteksi kamus data entri, file- file
data, tabelspace dan rollback segment.
• Distributed lock- digunakan untuk memprotek data dalam sebuah
lingkungan distribusi dan atau parallel server
• PCM locks- Parallel cache management (PCM) lock digunakan untuk
memproteksi buffer cache dalam sebuah lingkungan parallel server.
14
Oracle mengenal 2 level konsistensi baca, yaitu statement-level read
consistency (konsistensi baca level statement) dan transaction-level read
consistency (konsistensi baca level transaksi).
1. Konsistensi Baca Level-Statement (Statement-Level Read Consistency)
Oracle secara otomatis senantiasa menyelanggarakan konsistensi baca
pada level statemen. Hal ini menjamin setiap data yang dikembalikan oleh sebuah
query berasal dari sebuah titik tunggal (single point) dalam waktu dimana query
tersebut dimulai. Oleh karena itu, sebuah query tidak pernah melihat data
kotor/dirty read maupun setiap perubahan yang dilakukan oleh transaksi lain yang
commit selama query tersebut dieksekusi. Hasilnya yaitu hanya data yang commit
sebelum query mulai yang dapat dilihat oleh query. Query tersebut tidak melihat
perubahan commit setelah eksekusi statement mulai. Sebuah hasil yang konsisten
dibangun untuk setiap query, menjamin kekonsistenan data, dan dalam hal ini
tidak memerlukan aksi apapun dari user. Statement-statement SQL seperti
SELECT, INSERT, UPDATE, dan DELETE menggunakan sebuah query untuk
menetapkan data mana yang akan dipengaruhi. SELECT statement merupakan
sebuah query explicit dan dapat mempunyai query bersarang atau operasi join.
Sebuah statement INSERT dapat menggunakan beberapa query bersarang.
UPDATE dan DELETE statement dapat mengggunakan klausa WHERE atau
subquery-subquery untuk menghasilkan hanya beberapa baris dalam sebuah tabel
lebih daripada semua baris.
Beberapa query yang digunakan oleh INSERT, UPDATE dan DELETE
statement dijamin menghasilkan set hasil yang konsisten. Query dalam operasi-
15
operasi hanya melihat data yang telah ada sebelum operasi mulai untuk membuat
perubahan.
2. Konsistensi Baca Level-Transaksi (Transaction-Level Read Consistency)
Konsistensi baca Level-Transaksi ini berjalan di sebuah transaksi yang
berjalan menggunakan jenis isolation level serializable. Semua data mengakses
gambaran suatu keadaan dari database seperti pada saat sebuah transaksi mulai.
Hal ini berarti data yang dilihat oleh semua query pada transaksi yang sama
merupakan konsisten dengan pasti pada sebuah titik tunggal (single point) dalam
waktu, kecuali jika beberapa query dibuat oleh sebuah transaksi serializable
melihat perubahan yang dibuat transaksi tersebut. Konsistensi baca level-transaksi
menghasilkan pembacaan yang repeatabel dan tidak membuka sebuah query untuk
masalah phantom.
2.3.2. Macam-macam Level Isolasi Oracle
Oracle menyediakan 3 level isolasi yaitu READ COMMITTED,
SERIALIZABLE dan READ ONLY. Oracle hanya mengimplementasikan 2 dari 4
level isolasi yang didefenisikan dalam ISO SQL Standar.
• READ COMMMITTED. Serialisasi didukung pada level isolasi ini
didukung pada statement level (itu adalah default level isolasi), yang mana
setiap statement didalam transaksi hanya melihat data yang telah di
committed sebelum statement (bukan transaksi) dimulai. Ini berarti bahwa
data mungkin diubah oleh transaksi lain selama eksekusi dari statement
16
yang sama didalam transaksi yang sama, mengijinkan non-repeatabel dan
phantom.
• SERIALIZABLE. Serialisasi didukung pada transaksi level jadi, setiap
statement didalam sebuah transaksi melihat hanya data yang telah di-
committed sebelum transaksi dimulai.
• READ ONLY. Transaksi READ ONLY melihat hanya data yang committed
sebelum transaksi dimulai.
READ COMMMITTED dan SERIALIZABLE menggunakan row-level locking dan
keduanya menunggu jika sebuah transaksi mencoba untuk mengubah sebuah baris
yang diupdate oleh sebuah transaksi yang uncommitted. Jika transaksi yang
dibloking commit, dan melepaskan setiap lock, kemudian dengan mode READ
COMMITTED, transaksi menunggu berproses dengan updatenya. Bagaimanapun
juga, dengan mode SERIALIZABLE sebuah error bisa mengindikasikan operasi
tersebut tidak bisa diserialisasikan.
Level isolasi dapat diset di Oracle, dengan memilih salah satu dari level
isolasi yang akan dipakai pada awal transaksi dimulai. Seperti:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET TRANSACTION READ ONLY;
Dapat juga menggunakan perintah ALTER SESSION untuk mengeset level isolasi
pada transaksi untuk semua subsequent transaksi, seperti:
ALTER SESSION SET ISOLATION_LEVEL SERIALIZABLE;
ALTER SESSION SET ISOLATION_LEVEL READ COMMITTED;
17
2.3.3. Deteksi Deadlock
Oracle secara otomatis mendeteksi dan menangani deadlock dengan cara
me-rollback satu dari perintah yang terdapat dalam deadlock. Sebuah pesan
dikembalikan pada sebuah transaksi yang memiliki perintah yang di-rollback.
2.4 Database Oracle 10g Oracle 10g adalah software databse terbaru dari perusahaan database
terkenal didunia Oracle Corp. Oracle merupakan salah satu software database
ORDBMS (Object Relational Database Management System). Beberapa
kelebihan utama dari Oracle 10g:
1. Mendukung penuh RDBMS
2. Mempunyai fasilitas administrasi database yang memudahkan user mengatur
database dengan tampilan GUI yang memuaskan
3. Mendukung penuh aplikasi Internet dan Windows.
Selain itu, Oracle 10g mempunyai fitur baru dibandingkan pendahulunya, antara
lain:
1. Automatic Storage Management. Automatic Storage Management
memungkinkan pembuatan pembuatan sebuah kelompok disk dari
sekumpulan peranti disk.
2. Instalasi komponen terpisah. Beberapa komponen saat ini tidak diinstal
pada media instalasi database Oracle.
18
3. Enkripsi password database. Password setiap user yang mencoba remote
login ke Oracle Database 10g release 1 (10.1) otomatis dienkripsi sebelum
dikirim ke remote.
4. Data Pump Import dan Export. Oracle menggunakan fasilitas impor dan
ekspor yang lebih cepat untuk transfer file.
5. Large Page Support. Large page support menyediakan peningkatan
kecepatan kinerja untuk penggunaan memori yang berjalan di Windows
Server 2003.
6. Oracle Data Provide for .NET. Fasilitas Oracle Data Provider for .NET
(ODP.NET) 10g release 1 (10.1) termasuk berikut:
Mendukung Oracle grids (teknologi Grid Computing).
Mendukung tipe data baru di database, yaitu BINARY_FLOAT
dan BINARY_DOUBLE.
Mendukung Oracle homes yang banyak.
Mendukung schemea-based XML Type di database.
7. Oracle Enterprise Manager Database Control. Oracle Enterprise
Manager Database Control diinstal pada home yang sama sebagai
database dan mendukung instance standalone Oracle Containers for Java
(OC4J).
Database Oracle 10g dapat diakses oleh multiuser secara bersamaan.
Oracle 10g juga dapat diakses dengan mudah dengan adanya fasilitas ODBC
(Open Database Connectivity) yang dapat diakses oleh banyak program seperti
vb.net, java, dll.
19
2. 5 Pemrograman Database dengan Oracle PL/SQL
Procedural Language/SQL (PL/SQL) dibutuhkan untuk mengekstrak
informasi atau mengaksiplasikan perubahan ke database secara pemrograman. Hal
ini karena PL/SQL mendukung manipulasi data dan kontrol transaksi yang tidak
dapat dilakukan oleh SQL. Perbedaan SQL dengan PL/SQL ialah PL/SQL bukan
unit transaksi. Fungsi commit, savepoint, dan roolback independent terhadap blok,
tapi perintah tersebut dapat diaktifkan di dalam blok. PL/SQL tidak mendukung
Data Definition Language (DDL) dan Data Control Language(DCL).
Blok dari PL/SQL yang umum ialah:
Berikut ini tipe data pada PL/SQL:
Tabel 2.2 berikut merupakan tipe-tipe data dalam Oracle PL/SQL :
Tipe Variabel Penjelasan Contoh
VARCHAR2 Variable-length
Character string
Name VARCHAR2(35);
CHAR Fixed-lebgth character
string
Middle_init
VARCHAR2(1);
DATE Tanggal Middle_init
VARCHAR2(1);
declare -- optional begin
-- mandatory -- statement PL/SQL exception -- optional -- pernyataan error handling end; -- mandatory
20
NUMBER Floating, fixed, atau
bilangan bulat
Birth_date DATE;
LONG Long text hingga 32760
bytes
Price NUMBER(4);
BINARY_INTEGER Bilangan bulat Comment LONG;
INTEGER Bilangan bulat Counter
BINARY_INTEGER;
INT Bilangan bulat Counter INTEGER;
SMALLINT Bilangan bulat Counter INT;
DEC Floating point Counter SMALLINT;
DECIMAL Floating point Price DEC;
DOUBLE Floating point Price DOUBLE;
PRECISION Floating point Price PRECISION;
NUMERIC Floating point Price NUMERIC;
REAL Floating point Price REAL;
BOOLEAN True atau false is_customer BOOLEAN;
LOB Large object Product_image LOB;
Tabel 2.2 Berbagai Tipe Data PL/SQL
Tabel 2.3 berikut ini merupakan operator-operator dalam PL/SQL:
Simbol Arti
+ Addition operator
- Subtraction/negation operator
* Multiplication operator
21
/ Division operator
= Relational operator
@ Remote access indicator
; Statement terminator
<> Relational operator
!= Relational operator
|| Concatenation operator
-- Single line comment indicator
/* Beginning comment delimiter
*/ Ending comment delimiter
:= Assignment operator
Tabel 2.3 Berbagai Operator PL/SQL
2.5.1 Mengambil Data di PL/SQL
Untuk mengakses data di PL/SQL, digunakan variable sebagai penampung
data sementara. Contoh:
declare emp_rec emp%rowtype; begin select * into emp_rec from emp where empno = &employee_number; dbms_output.put_line (‘nama pegawai’ || emp_rec.ename); end;
2.5.2 Memasukkan Data Menggunakan PL/SQL
Fungsi insert into nama_tabel values (…) digunakan untuk memasukkan
data. Contoh berikut ini akan memasukkan data di 3 kolom yang telah ditentukan.
Single quote (kutip 1) digunakan jika data bertipe string.
22
begin insert into emp (emp, ename, job, deptno) values (777, ‘Saftian’,’DBA’, 10); end;
2.5.3 Meng-update dan Menghapus Data
Untuk meng-update data, digunakan fungsi update nama_tabel set
nama_kolom sebagai berikut:
declare v_sal_increase emp.sal%type:=200; begin update emp set sal = sal+v_sal_increase where job = ‘ANALYST’ end;
2.5.4 Konvensi Nama
Nama fungi yang ada di Oracle tidak dapat digunakan sebagai variable.
Nama variable diusahakan tidak berbenturan dengan nama kolom. Contoh berikut
menampilkan kesalahan penggunaan nama variable dan kolom.
2.5.5 Mengontrol Transaksi
DECLARE orderdate ord.orderdate%TYPE; shipdate ord.shipdate%TYPE; ordid ord.ordid%TYPE := 601; BEGIN SELECT orderdate, shipdate INTO orderdate, shipdate FROM ord WHERE ordid = ordid; END; SQL> / DECLARE * ERROR at line 1: ORA-01422: exact fetch returns more than requested number of rows ORA-06512: at line 6
23
2.5.5 Mengontrol Transaksi
Fungsi commit digunakan untuk menyukseskan transaksi, sedangkan fungsi
rollback digunakan untuk menggagalkan transaksi. Secara default commit sudah
aktif, jadi tidak perlu menggunakan fungsi commit jika ingin menyukseskan
transaksi. Perintah rollback hanya dapat mengembalikan isi tabel ke kondisi
saat perintah commit terakhir kecuali jika perintah savepoint digunakan sehingga
perintah rollback dapat mengembalikan isi tabel ke kondisi savepoint yang telah
ditentukan. Savepoint berfungsi untuk memberikan rentang update pada data
sehingga kita dapat me-rollback perubahan data ke titik tertentu.
Contoh:
SQL> update kategori set penjelasan=’PL/SQL ; where no_kategori=1’;
Lalu berikan perintah:
SQL> commit;
Data di atas akan benar-benar berubah, tetapi jika perintah rollback dijalankan
sebelum commit seperti berikut:
SQL> rollback;
Maka data akan dibalikkan ke data awal. Untuk membuat perantara perubahan
data digunakan savepoint, seperti:
SQL> savepoint kategori_update;
Jika perintah rollback dieksekusikan to kategori_update, maka isi penjelasan
no_kategori akan kembali ke kondisi savepoint yang telah ditentukan.
24
2.6 Aplikasi Database C#.NET
2.6.1 Mengenal C#.NET
Microsoft Visual Studio .NET ialah perangkat pengembangan multibahasa
yang menyeluruh untuk membangun secara cepat dan memadukan XML Web
service dan aplikasi yang secara dramatis meningkatkan produktifitas. Visual
Studio. NET didesain dengan integrasi yang menggunakan standar Internet dan
protocol seperti XML dan SOAP (Simple Object Access Protocol).
2.6.2 Teknologi ADO.NET
ADO.NET ialah teknologi akses data universal terbaru, arsitekturnya mirip
ADO, tapi mempunyai banyak kelebihan dibandingkan pendahulunya. ADO.NET
berdasarkan prinsip tanpa koneksi (connectionless principle) yang didesain untuk
mempermudah batasan koneksi yang dulunya harus diperhatikan ketika membuat
aplikasi terdistribusi. Aplikasi hanya terhubung ke database untuk beberapa saat
guna mengakses atau memperbaharui data lalu diputus. Data yang diakses dapat
disimpan pada salah satu objek ADO.NET yaitu pada DataSet atau DataView.
Keuntungan disconnected architecture ialah mampu menangani lebih banyak user.
Kelebihan lain ialah karena data yang disimpan di DataSet berada di memori dan
berformat XML, maka data tersebut dapat digunakan pada aplikasi lainnya yang
mendukung XML. Saat ini Oracle telah menyediakan provider koneksi data di
.NET bernama Oracle Data Provider .NET (ODP .NET).
25
Tabel 2.4 merupakan namespace pada ADO.NET ialah sebagai berikut:
Namespace Penjelasan
System.Data Menangani objek utama seperti
DataTabel, DataView, dan constraint
System.Data.Common Mendefinisikan objek generic yang di-
sharing/dibagi oleh penyedia data yang
berbeda seperti DataAdapter,
DataColumnMapping, dan
DataTabelMapping. Namespace ini
digunakan oleh penyedia data (data
provider) dan berisi sekumpulan
fungsi-fungsi penting untuk mengakses
data.
Oracle.DataAccess.Client dan
Oracle.DataAccess.Types
Namespace minimal untuk penyedia
data yang dibuat khusus untuk Oracle
10g agar program .NET bisa terkoneksi
ke Oracle
Tabel 2.4 Namespace pada ADO.NET
Ada 3 komponen akses utama yang harus digunakan untuk mengakses dan
menyimpan data dari database, yaitu OracleConnection, OracleDataAdapter, dan
DataSet.
OracleConnection, OracleCommand, dan OracleDataAdapter didesain
untuk mengakses database Oracle dengan cara yang mudah. Setiap komponen ini
26
terletak pada toolbox di bawah tab Data. Selain itu agar dapat menggunakan
namespace Oracle, dapat ditambahkan juga references Oracle yang sesuai seperti
Oracle.DataAccess.dll.
2.6.2.1 OracleConnection
OleDbConnection merupakan komponen yang bertugas menangani
koneksi ke database dan menyediakan informasi-informasi data seperti nama
database, lokasi, dan driver database yang digunakan untuk berhubungan
dengan database menggunakan driver berekstensi .dll yang menyediakan kode
penting yang mengijinkan OracleConeetion untuk dapat berkomunikasi ke
database dengan caranya sendiri. Ada dua cara menghubungkan
OleDbConnection ke dalam aplikasi, pertama yatiu dengan langsung meletakkan
OracleConnection ke form kita dan mengtur propertinya atau dengan meletakkan
OracleDataAdapter di dalam form aplikasi dan secara otomatis akan
menambahkan OracleConnection dan meminta pembuat aplikasi untuk engatur
propertinya.
2.6.2.2 OracleDataAdapter dan DataSet
OracleDataAdapter adalah komponen yang memiliki banyak fungsi dan
tidak hanya menyediakan cara untuk mengambil data dari database, tapi juga
digunakan untuk memasukkan, memperbaharui, dan menghapus data pada
database. Komponen ini berfungsi juga sebagai jembatan antara database dan
objek DataSet yang akan mengambil data yang telah ditentukan lalu akan mengisi
27
DataSet tersebut. Komponen DataSet berfungsi sebagai cache data yang disimpan
di memori. DataSet tdak hanya menyimpan data yang diambil di
OracleDataAdapter tetapi menyimpan informasi tabel seperti data yang diambil
seperti nama kolom dan tipe datanya yang dikenal dengan nama metadata.
Metadata disimpan di dokumen XML.
2.6.2.3 OracleCommand
OracleCommand digunakan untuk mengeksekusi pernyataan SQL pada
database.
2.6.3 Membuat Koneksi Database
Untuk membuat koneksi ke database Oracle ialah dapat dilakukan dengan
control koneksi database OracleDataAdapter yang ada di toolbox, atau dengan
menggunakan Data Form Wizard atau dengan menggunakan kode. Untuk dapat
mengakses dan menampilkan data ke form, koneksi harus dibuat terlebih dahulu,
kemudian koneksi dibuka, lalu dataset dapat diisi. Dataset tersebut kemudian
dapat ditampilkan ke control datagrid. Oleh karena C#.NET sudah mendukung
OOP, maka harus dibuat objek dari kelas yang ada.
28
BAB III
ANALISA PERMASALAHAN
DAN PERANCANGAN SISTEM
3.1 Analisa Permasalahan
3.1.1 Permasalahan-permasalahan yang Timbul jika Tidak Terdapat
Penanganan Concurrency control
Permasalahan yang terjadi pada aplikasi untuk multiuser yaitu akses
bersama yang dilakukan oleh beberapa user pada waktu yang bersamaan pada
database dapat menyebabkan data yang tidak konsisten. Selama proses yang
dilakukan oleh setiap user yaitu hanya proses baca, masalah ketidakkonsistenan
dari data yang direpresentasikan kepada user tidaklah menjadi masalah. Namun,
lain halnya jika salah satu dari user tersebut melakukan operasi update, insert atau
delete. Penanganan concurrency control yang tidak baik dalam aplikasi tersebut
dapat menyebabkan data tidak konsisten. Berikut merupakan contoh kasus
masalah-masalah yang terjadi dalam aplikasi untuk teller bank dalam mengakses
rekening nasabah bank. Dalam kasus ini setiap teller bank memiliki hak yang
sama dalam mengakses database rekening nasabah bank.
29
1. Masalah Hilangnya Data (Lost of update).
Tabel 3.1 merupakan tabel ilustrasi masalah hilangnya data yang diupdate
Wak
tu
Teller A
Teller B
Total saldo Nasabah A (saldo A)
Total saldo Nasabah B (saldo B)
t1 Begin transaction 10.000.000 1.000.000 t2 Read (saldo A) 10.000.000 1.000.000 t3 Saldo A=saldo A – 1.000.000 10.000.000 1.000.000 t4 Write (saldo A) 9.000.000 1.000.000 t5 read (saldo B) begin transaction 9.000.000 1.000.000 t6 saldo B=saldo B+1.000.000 read (saldo B) 9.000.000 1.000.000 t7 write (saldo B) saldo B=saldo B-500.000 9.000.000 2.000.000 t8 Commit write (saldo B) 9.000.000 500.000 t9 Commit 500.000
Tabel 3.1 Tabel Ilustrasi Masalah Hilangnya Data Yang Diubah
Contoh kasus diatas:
Nasabah B merupakan seorang mahasiswa di kota Yogya,
sedangkan Nasabah A merupakan orangtua Nasabah B yang berada dilain
kota. Nasabah A bermaksud mengirimkan uang bulanan kepada anaknya,
Nasabah B, melalui kantor cabang terdekat dikotanya, yang dilakukan oleh
seorang Teller A. Teller A melakukan transaksi transfer saldo dari no
rekening nasabah A menuju no rekening nasabah B dengan nominal Rp.
1.000.000. Namun ternyata, nasabah B, sedang melakukan transaksi
penarikan tunai yang dilayani oleh Teller B dengan nominal Rp. 500.000
dalam waktu interfal yang sama.
Hilangnya perubahan data terhadap saldo B yang dilakukan oleh Teller A
dapat terjadi karena Teller B diijinkan membaca nilai saldo B, padahal
transaksi yang dilakukan oleh Teller A belum selesai.
30
Dapat diperhatikan, bahwa dengan tidak adanya concurrency control
dalam database untuk akses bersama dapat mengakibatkan kerugian pada
nasabah B sebesar Rp. 1.000.000
2. Masalah Analisa Yang Tidak Konsisten (The inconsistent analysis
problem).
Tabel 3.2 merupakan tabel ilustrasi masalah Analisa Yang Tidak Konsisten
Wak
tu
Teller A
Teller 1
Total saldo Nasabah A (saldo A)
Total saldo Nasabah D (saldo D)
Total Jumlah
saldo semua
nasabah
T1 Begin Transaction 1.000.000 2.000.000 0 T2 Begin transaction Jumlah=0 1.000.000 2.000.000 0 T3 Read (saldo A) Read (saldo A) 1.000.000 2.000.000 0 T4 Saldo A=saldo A-200.000 Jumlah=jumlah+saldo A 1.000.000 2.000.000 1.000.000 T5 Write (saldo A) Read (saldo B) 800.000 2.000.000 1.000.000 T6 Read (saldo D) Jumlah=jumlah+saldo B 800.000 2.000.000 1.500.000 T7 Saldo D=saldo D+200.000 Read (saldo C) 800.000 2.000.000 1.500.000 T8 Write (saldo D) Jumlah=jumlah +saldo C 800.000 2.200.000 2.000.000 T9 Read(saldo D) 800.000 2.200.000 2.000.000 T10 Jumlah=jumlah+saldo D 800.000 2.200.000 4.200.000 T11 … … …
Tabel 3.2 Tabel Ilustrasi Masalah Analisa Yang Tidak Konsisten
Misal: Saldo B sebesar Rp. 500.000 Saldo C sebesar Rp. 500.000
Contoh kasus:
Misalnya didalam Bank terdapat 4 orang nasabah. Manager Keuangan
Kantor Pusat meminta seorang Teller untuk membuat laporan berupa jumlah total
saldo seluruh nasabah yang ada di Bank tersebut. Teller 1 melakukan proses
penjumlahan seluruh saldo nasabah Bank dengan menggunakan Transaksi jumlah
saldo seluruh nasabah yang terdapat di Menu aplikasi untuk Teller Bank. Namun,
31
pada saat yang bersamaan ada rang nasabah, yakni nasabah A melakukan
transaksi transfer saldo dari rekeningnya menuju rekening nasabah D sebesar Rp.
200.000. Padahal Transaksi yang dilakukan Teller 1 telah terlebih dahulu
merekam nilai saldo Nasabah A pada awalnya yaitu sebesar Rp. 1.000.000.
Hal ini dapat terjadi karena disebabkan transaksi yang dijalankan oleh Teller 1
dapat membaca nilai saldo Nasabah A sebelum transaksi oleh Teller A selesai
melakukan update.
Dapat diperhatikan, bahwa dengan tidak adanya concurrency control dalam
database untuk akses bersama dapat mengakibatkan kesalahan data dalam
menjumlahkan seluruh saldo nasabah bank sebesar Rp. 200.000
3.1.2. Sistem yang Dikembangkan
Sistem yang dibangun merupakan system yang didalamnya terdapat
management transaksi berupa concurrency control untuk menjamin konsistensi
data yang diakses secara bersama-sama oleh lebih dari satu user pada saat yang
bersamaan. Oracle menggunakan sebuah protokol multiversion read consistency
untuk menjamin kekonsistenan data untuk setiap user. Untuk itu, system yang
dibangun akan mempresentasikan beberapa kemungkinan penanganan terhadap 2
masalah yang terjadi dengan beberapa pendekatan, yaitu :
1. Menggunakan jenis Oracle Isolation level yaitu SERIALIZABLE level pada
pada awal transaksi.
2. Memanfaatkan mekanisme Locking secara otomatis dalam Oracle pada
beberapa perintah SQL statement, seperti :
32
i. Statement UPDATE pada diri sendiri sebelum melakukan
statement SELECT jika sebuah transaksi berupaya untuk
mengubah sebuah baris, merupakan sebuah cara untuk tetap
menjaga kekonsistenan data pada baris yang dibaca.
Exclusive row-locks diberlakukan pada baris yang diakses,
sedangkan row exclusive mode lock pada tabel yang diakses.
ii. Statement SELECT… FOR UPDATE pun dapat digunakan
untuk menjamin kekonsistenan baca data yang hendak
diubah. Exclusive row-locks diberlakukan pada baris yang
diakses, sedangkan row-share lock mode pada tabel yang
diakses.
33
3.1.3. Requirement Analysis
Gambar 3.1 merupakan gambar use case diagram.
Login Teller
Logout Teller
Mengakses Data Nasabah dengan Transaksi Penarikan
Tunai
Mengakses Data Nasabah dengan Transaksi Penyetoran
Tunai
Mengakses Data Nasabah dengan Transaksi Transfer
Saldo
Menghitung Total Saldo seluruh Nasabah
Gambar 3.1 Use Case Diagram
34
3.1.4. Data Modelling
Gambar 3.2 merupakan gambar ER Diagram
Jenis_transaksi
Nama_teller
Nominal_kredit
Nasabah Jenis_transaksi
Teller
Transaksi
Nama_nasabah No_Rekening
Alamat
No_telp
Tanda_pengenal
No_buku_rek
Kantor_cabang
Total_saldo
No_Rekening
Waktu
NIK
Kantor_cabang
NIK
Nominal_debet
Id_jenis_transaksi Id_jenis_transaksi
(0, N)(0, N)
(1, 1)
Id_transaksi
Alamat
Saldo
Nominal_kredit
Nama_teller
Nasabah Jenis_transaksi
Teller
Transaksi
Nama_nasabah No_Rekening
Alamat
No_telp
Tanda_pengenal
No_buku_rek
Kantor_cabang
Total_saldo
No_Rekening
Waktu
NIK
Kantor_cabang
NIK
Nominal_debet
Id_jenis_transaksi Id_jenis_transaksi
(0, N)(0, N)
(1, 1)
Id_transaksi
Alamat
Saldo Oleh
Id_nasabah
Gambar 3.2 ER-Diagram
35
3.1.5 Proses Modelling 3.1.5.1 Context Diagram
NIK, Password, No_rek, No_rek tujuan, Jenis_transaksi, Nominal_debet, Nominal_kredit
O Teller Bank Sistem Aplikasi
untuk Teller Bank
Informasi status transaksi, informasi data nasabah, informasi data nasabah tujuan, informasi NIK tidak valid, informasi total saldo seluruh nasabah
Gambar 3.3 Context Diagram 3.1.5.2 Diagram Berjenjang
O
Sistem Aplikasi untuk
Teller Bank
1P
Login Teller
6P
Logout Teller
2P Akses Data
Nasabah dengan
Transaksi Penarikan
Tunai
4P
Akses Data Nasabah dengan
Transaksi Transfer
Saldo
3P Akses Data
Nasabah dengan
Transaksi P
3P Akses Data
Nasabah dengan
Transaksi P
3P
Akses Data Nasabah dengan
Transaksi Penyetoran
Tunai
5P
Hitung Total Saldo
seluruh Nasabah
Gambar 3.4 Diagram Berjenjang
36
3.1.5.3 Data Flow Diagram
Read NIP
keluar nformasi data nasabah, informasu status transaksi
I
I
Teller Bank
Informasi Total_saldo slrh Nasabah
Login Teller Bank
Akses Data bah
gan
rikan
Nasaden
Transaksi Pena
Tunai
3P Akses Data
bah dengan
Nasa
Transaksi Penyetoran
Tunai
3P Akses Data
bah dengan
Nasa
Transaksi Penyetoran
Tunai
Akses Data
bah dengan
Nasa
Transaksi Penyetoran
Tunai
Akse
Nasas Data
bah gan
Transaksi Transfer
Saldo
den
Hitung Total Saldo seluruh
Nasabah
D3 Teller
D3
NIP
Status Login, NIK tidak valid
Read No rek
InformNIK tidak
asi
valid
6P
Logout Teller Bank
Gambar 3.5 Data Flow Diagram
Teller
No Rek, Jenis Transaksi, Nominal_debe
No Rek, Jenis Transaksi, Nominal_kredit
Nominal_debet,No_rek tujuan
lah
1P
4P
formasi data bah
formasi Status Transaksi
Read Total saldo
2P
No Rek, Jenis Transaksi,
Jum
3P
5P
In Nasa
In
Informasi data Nasabah, data Nasabah
formasi data Nasabah ata Transaksi
Write data Transaksi
k
formasi data nasabah, informasu status transaksi
Transaksi
Nasabah
Nasabah
Transaksi
D1 Nasabah
Transaksi
D1 Nasabah
D2 Transaksi
formasi Status Transaksi
formasi data nasabah, informasu status transaksi
ead No_rek, No_rek_tujuan
ata Transaksi
formasi Status Transaksi
formasi data Nasabah ata Transaksi
Informasi Status Transaksi
s Logout
D1
Inwrite d
D2
In
Read No_reD1
D2
In
In
R
Write d
D2
In
Statu
InWrite d
37
3.2. Perancangan Sistem
3.2.1. Perancangan Database
Terdapat 4 tabel dalam database server, yaitu tabel Nasabah, Tabel
Jenis_transaksi, Tabel Transaksi, dan Tabel Teller. Tabel Transaksi mencatat
transaksi yang terjadiyang dilakukan oleh Teller Bank dalam melayani permintaan
Nasabah. Gambar 3.6 merupakan relasi antar tabel-tabel yang ada dalam database:
Tabel Nasabah Tabel Jenis_transaksi Tabel Transaksi Tabel Teller
* No_rekening Nama_nasabah Alamat No_telp Tanda_pengenal No_buku_rek Kantor_cabang Total_saldo Id_nasabah
* Id_jenis transaksi jenis_transaksi
* Id_transaksi **Id_jenis_transaksi **No_rekening **NIK Waktu Nominal_debet Nominal_kredit Saldo
* NIK Nama Alamat Kantor_cabang
Gambar 3.6 Gambar Tabel Relasi Transaksi Pada Teller Bank
38
Dari tabel-tabel yang terbentuk, berikut merupakan struktur datanya:
Tabel Nasabah:
Nama Field Tipe PK. No_rekening Number(15) Nama_nasabah Varchar2(50) Alamat Varchar(50) No_telp Number(13) Tanda_pengenal Varchar(25) No_buku_rek Number(8) Kantor_cabang Varchar2(25) Total_saldo Number(15) Id_nasabah Number
Tabel 3.3 Struktur Tabel Nasabah
Tabel Jenis_transaksi:
Nama Field Tipe PK. Id_jenis_transaksi Number(2) Nama_jenis_transaksi Varchar2(30)
Tabel 3. 4 Struktur Tabel Jenis Transaksi Tabel Transaksi:
Nama Field Tipe PK. Id_transaksi Int FK. Id_jenis_transaksi Number(2) FK. No_rekening Number(15) FK. NIK Number(5) Waktu Date Nominal_debet Number(15) Nominal_kredit Number(15) Saldo Number(15)
Tabel 3.5 Struktur Tabel Transaksi Tabel Teller Bank:
Nama Field Tipe PK. NIK Number(5) Nama_teller Varchar2(50) Alamat Varchar(50) Kantor_cabang Varchar2(25)
Tabel 3.6 Struktur Tabel Teller Bank
39
BAB IV
IMPLEMENTASI SISTEM
4.1 Karakteristik Sistem
Setelah selesai merancang dan menganalisa sistem yang akan dibuat,
dalam tahap ini akan dicoba bagaimana mengimplementasikan sistem kedalam
aplikasi berupa simulasi untuk Teller Bank dalam mengakses rekening nasabah
Bank.
Sistem yang dibangun dapat digunakan lebih dari 1 Teller Bank, atau
secara multiuser, dalam suatu waktu. Implementasi Concurrency control dalam
Oracle dibangun dengan menggunakan isolation level jenis SERIALIZABLE, dan
juga memanfaatkan statemet-statement pada SQL seperti statement SELECT...
FOR UPDATE dan statement UPDATE sebelum membaca data yang hendak
diubah, sehingga dapat melindungi data, dan menghasilkan hasil yang
sesungguhnya (valid) dan konsisten.
Terdapat 2 pilihan dalam mengakses aplikasi untuk Teller Bank, yaitu
pilihan aplikasi berjalan dengan tidak menggunakan concurrency control, dan
pilihan aplikasi berjalan dengan menggunakan concurrency control. Masing-
masing aplikasi memiliki 4 jenis pilihan transaksi, yaitu transaksi penarikan tunai,
transaksi penyetoran tunai, transaksi transfer saldo dan transaksi jumlah total
saldo nasabah.
40
4.2 Kebutuhan Sistem
Server
• Sistem operasi windows 2000 server atau windows 2003 server
• Oracle 10g XE
Client
• Sistem operasi windows 98 atau windows 2000 atau windows XP
• Net. Framework
4.3 Setting Koneksi Oracle 10g XE ke C#.Net
1. Untuk mengkoneksikan C#.net dengan database Oracle, diperlukan tambahan
reference dari Oracle.DataAccess.dll, yang berisi penyedia data (sebagai data
provider). Oracle.DataAccess.dll ini dapat ditemukan di tambahan reference
pada Solution Explorer.
2. Dibutuhkan C# using statement untuk mengijinkan program c#.net untuk
menghubungi objek-objek database, seperti :
using Oracle.DataAccess.Client; using Oracle.DataAccess.Types;
3. Objek OracleConnection menspesifikasikan database Oracle digunakan pada
aplikasi C#. Kemudian dibuat kelas Koneksi.cs yang mengatur
OracleConnection, sehingga dapat dipanggil setiap saat dalam setiap form
aplikasi yang ada.
41
using Oracle.DataAccess.Client; using Oracle.DataAccess.Types; public class Koneksi { private static string con_str; public Koneksi() { } static Koneksi() { con_str = @"user id=grace;data source=;password=grace"; // Untuk koneksi ke database } public static string CON_STR { get { return con_str; } } public static OracleConnection CON { get { return new OracleConnection(con_str); } } }
4. Pada setiap form aplikasi yang membutuhkan koneksi terhadap database
Oracle, dibutuhkan perintah berikut :
private OracleConnection conn = Koneksi.CON;
Perintah tersebut untuk memanggil kelas Koneksi.CON pada kelas
Oracle.DataAccess.Client.OracleConnection dengan menggunakan variable
conn.
5. Koneksi dengan Oracle database dapat dibuka ketika memanggil perintah
berikut :
conn.Open();
6. Koneksi dengan Oracle database dapat ditutup dengan memanggil perintah
berikut :
conn.Close();
42
Berikut merupakan cara-cara membangun sebuah Oracle Data Provider
untuk aplikasi C#.NET :
1. Kelas OracleCommand menspesifikasikan perintah SQL, stored procedure,
atau nama tabel. OracleCommand menciptakan sebuah permintaan terhadap
database, mengirimkannya dan mengembalikan hasilnya. Seperti pada
perintah berikut :
string sql = "select * from Nasabah where No_rekening= '"
+noRekText.Text+"'";
Perintah diatas berarti mespesifikasikan perintah SQL dalam sebuah variable
sql bertipe data string. No_rekening diambil dari masukan pada TextBox
noRekText oleh user.
2. Perintah berikut diperlukan untuk meng-query database :
cmd = new OracleCommand(sql, conn); cmd.CommandType = CommandType.Text;
3. DataSet diperlukan untuk mengisi hasil dari perintah query. Oleh karena itu,
diperlukan C# using statement berikut :
using System.Data;
4. Variable-variabel berikut dibawah ini digunakan untuk menggunakan kelas
DataSet.
private OracleCommand cmd; private OracleDataAdapter da; private OracleCommandBuilder cb;
private DataSet ds;
5. Untuk memanggil variable-variabel tersebut, diperlukan perintah berikut :
da = new OracleDataAdapter(cmd); cb = new OracleCommandBuilder(da); ds = new DataSet();
43
6. Berikut merupakan perintah untuk mengisi DataSet ds dengan hasil dari
perintah query sebelumnya.
da.Fill(ds);
7. Berikut merupakan perintah untuk mengikat dataset ke data grid Nasabah.
Nasabah.DataSource = ds.Tabels[0];
4.4 Pembuatan Antar Muka Pemakai (User interface)
4.4.1. User interface Form Utama
Gambar 4.1 merupakan gambar user interface dari Form Utama
Gambar 4.1 Form Utama
Form Utama ini merupakan halaman utama aplikasi untuk Teller Bank,
dimana user diminta untuk memilih hendak melaksanakan program tanpa
menggunakan implementasi concurrency control, atau dengan menggunakan
44
implementasi concurrency control. Masing-masing pilihan akan menuju Form
Login Teller Bank.
4.4.2 User interface Form Login Teller Bank
Gambar 4.2 merupakan gambar user interface dari Form Login Teller
Bank untuk aplikasi tanpa concurrency control.
Gambar 4.2 Form Login Teller Bank untuk Aplikasi Tanpa Concurrency control
45
Gambar 4.3 merupakan gambar user interface dari Form Login Teller
Bank untuk aplikasi dengan concurrency control.
Gambar 4.3 Form Login Teller Bank untuk
Aplikasi Dengan Concurrency control
Form Login Teller Bank memerlukan masukan dari user berupa Nama
Teller dan NIK (Nomor Induk Karyawan). Masukan Nama Teller dan NIK akan
diproses begitu user menekan tombol Lanjut. Form akan mengeluarkan peringatan
jika masukan Teller Bank dan NIK tidak sesuai dengan data dalam tabel Teller
Bank. Berikut merupakan program yang memeriksa valid atau tidaknya seorang
pengguna untuk memasuki aplikasi, perintah ini diproses ketika user menekan
tombol Lanjut/OK :
46
private void okButton_Click(object sender, System.EventArgs e) {
try { conn.Open(); string query = "Select * from Teller_bank Where nik = '" +nikText.Text.Trim()+"'"; OracleCommand comd = new OracleCommand(query,conn); OracleDataReader reader = comd.ExecuteReader();
if(reader.HasRows) { reader.Read();
if(nikText.Text.Trim()==reader.GetString(0)&& namaTellerText.Text.ToUpper()==reader.GetString(1))
// GetString(0) berdasarkan field di Tabel Teller, 0 untuk NIK, 1 untuk Nama_Teller, 2 untuk Alamat, 3 untuk Kantor_cabang
{ MenuUtamaForm form = new MenuUtamaForm(); //Menuju halaman berikut form.nikText = nikText; form.Show(); this.Close(); } else { nikText.Clear(); namaTellerText.Clear(); MessageBox.Show("Nama Teller atau NIK Salah"); nikText.Focus(); } }
else { namaTellerText.Clear(); nikText.Clear(); MessageBox.Show("Nama Teller dan NIK Salah"); namaTellerText.Focus(); }
} catch (OracleException ex)
{ MessageBox.Show(ex.ToString()); }
catch(Exception e1) { MessageBox.Show(e1.ToString()); }
finally { conn.Close(); } }
47
4.4.3 User interface Menu Utama
Gambar 4.4 merupakan gambar user interface Menu Utama untuk aplikasi
tanpa concurrency control.
Gambar 4.4 Form Menu Utama untuk Aplikasi Tanpa Concurrency control
48
Gambar 4.5 merupakan gambar user interface Menu Utama untuk aplikasi
dengan concurrency control.
Gambar 4.5 Form Menu Utama untuk Aplikasi Dengan Concurrenc Control
Form Menu Utama memerlukan masukan no rekening nasabah dan juga
masukan pilihan terhadap jenis transaksi yang ada. Dalam form ini terdapat 4 jenis
transaksi, yaitu Transaksi Penarikan, Transaksi Penyetoran, Transaksi Transfer
Saldo dan Transaksi Total Saldo Seluruh Nasabah. Tombol Lanjut akan
memproses masukan yang ada, dengan perintah berikut ini :
49
private void lanjutButton_Click(object sender, System.EventArgs e) { try { conn.Open(); string query = "Select * from Nasabah Where No_Rekening = '" +noRekText.Text.Trim()+"'"; OracleCommand cmd = new OracleCommand(query,conn); OracleDataReader reader = cmd.ExecuteReader(); if(reader.HasRows) { if (penarikanRB.Checked) { string sql = " select * from jenis_transaksi where id_jenis_transaksi = 1"; OracleCommand comd2 = new OracleCommand(sql, conn); OracleDataReader reader2 = comd2.ExecuteReader();
da = new OracleDataAdapter(comd2); cb = new OracleCommandBuilder(da);
ds = new DataSet(); da.Fill(ds);
Jenis_transaksi.DataSource = ds.Tabels[0]; DataGridCell dgcJenis_transaksi = Jenis_transaksi.CurrentCell; idJenisTransaksiText.Text = Jenis_transaksi[dgcJenis_transaksi.RowNumber,0].ToString(); if (reader.HasRows) { this.Hide(); //memanggil FormPenarikan() FormPenarikan form1 = new FormPenarikan(); form1.idJenisTransaksiText.Text = idJenisTransaksiText.Text; form1.noRekText = noRekText; form1.nikText = nikText2; //berikut perintah untuk menampilkan FormPenarikan DialogResult result = form1.ShowDialog(); penarikanRB.Checked=false; } }
else if(penyetoranRB.Checked) { string sql = " select id_jenis_transaksi from jenis_transaksi where id_jenis_transaksi = 2"; OracleCommand comd2 = new OracleCommand(sql, conn); OracleDataReader reader2 = comd2.ExecuteReader();
da = new OracleDataAdapter(comd2); cb = new OracleCommandBuilder(da); ds = new DataSet();
da.Fill(ds); Jenis_transaksi.DataSource = ds.Tabels[0]; DataGridCell dgcJenis_transaksi = Jenis_transaksi.CurrentCell; idJenisTransaksiText.Text = Jenis_transaksi[dgcJenis_transaksi.RowNumber,0].ToString();
if (reader.HasRows) { this.Hide(); //memanggil FormPenyetoran() FormPenyetoran form2 = new FormPenyetoran(); form2.idJenisTransaksiText = idJenisTransaksiText; form2.noRekText = noRekText; form2.nikText = nikText2; //berikut perintah untuk menampilkan FormPenyetoran DialogResult result = form2.ShowDialog(); penyetoranRB.Checked=false; } }
50
else if (transferSaldoRB.Checked) { string sql = " select id_jenis_transaksi from jenis_transaksi where id_jenis_transaksi = 3"; OracleCommand comd2 = new OracleCommand(sql, conn); OracleDataReader reader3 = comd2.ExecuteReader(); da = new OracleDataAdapter(comd2); cb = new OracleCommandBuilder(da); ds = new DataSet();
da.Fill(ds); Jenis_transaksi.DataSource = ds.Tabels[0]; DataGridCell dgcJenis_transaksi = Jenis_transaksi.CurrentCell; idJenisTransaksiText.Text = Jenis_transaksi[dgcJenis_transaksi.RowNumber,0].ToString(); if (reader.HasRows) { this.Hide(); //memanggil FormTransferSaldo1() FormTransferSaldo1 form3 = new FormTransferSaldo1(); form3.idJenisTransaksiText = idJenisTransaksiText; form3.noRekText = noRekText; form3.nikText = nikText2; //berikut perintah untuk menampilkan FormTransferSaldo1 DialogResult result = form3.ShowDialog(); transferSaldoRB.Checked=false; } } else if (totalSaldoRB.Checked) { string sql = " select id_jenis_transaksi from jenis_transaksi where id_jenis_transaksi = 4"; OracleCommand comd2 = new OracleCommand(sql, conn); OracleDataReader reader4 = comd2.ExecuteReader(); da = new OracleDataAdapter(comd2); cb = new OracleCommandBuilder(da); ds = new DataSet(); da.Fill(ds); Jenis_transaksi.DataSource = ds.Tabels[0]; DataGridCell dgcJenis_transaksi = Jenis_transaksi.CurrentCell; idJenisTransaksiText.Text = Jenis_transaksi[dgcJenis_transaksi.RowNumber,0].ToString();
51
if (reader.HasRows) { this.Hide(); //memanggil FormTotalSaldo() FormTotalSaldo form4 = new FormTotalSaldo(); form4.idJenisTransaksiText = idJenisTransaksiText; DialogResult result = form4.ShowDialog(); totalSaldoRB.Checked=false; } } else { MessageBox.Show(" Silakan memilih Jenis Transaksi", "Jenis Transaksi diperlukan", MessageBoxButtons.OK, MessageBoxIcon.Information); } } else { noRekText.Clear(); MessageBox.Show("No Rekening tidak ada, masukan salah"); noRekText.Focus(); } } catch (OracleException ex)
{ MessageBox.Show(ex.ToString()); }
catch(Exception e1) { MessageBox.Show(e1.ToString()); }
finally { conn.Close(); }
}
52
4.4.4. User interface Form Transaksi Penarikan Tunai
Gambar 4.6 merupakan gambar user interface Form Transaksi Penarikan
Tunai untuk aplikasi tanpa concurrency control.
Gambar 4.6 Form Transaksi Penarikan Tunai untuk Aplikasi Tanpa Concurrency
Control
53
Gambar 4.7 merupakan gambar user interface Form Transaksi Penarikan
Tunai untuk aplikasi dengan concurrency control
Gambar 4.7 Form Transaksi Penarikan Tunai untuk Aplikasi Dengan
Concurrency Control
Form ini berisikan keluaran data nasabah yang disimpan dalam tabel
nasabah dalam database berdasarkan data masukan dalam Form Menu Utama
berupa no rekening nasabah. Berikut merupakan perintah yang digunakan ketika
Form ini dipanggil :
54
privat void FormPenarikan_Load(object sender, System.EventArgs e) e { // Untuk data nasabah ybs conn.Open(); string sql = "select * from Nasabah where No_rekening= '" +noRekText.Text+"'"; cmd = new OracleCommand(sql, conn); cmd.CommandType = CommandType.Text; da = new OracleDataAdapter(cmd); cb = new OracleCommandBuilder(da); ds = new DataSet(); da.Fill(ds); Nasabah.DataSource = ds.Tabels[0]; DataGridCell dgcNasabah = Nasabah.CurrentCell; noRekText2.Text = Nasabah[dgcNasabah.RowNumber,0].ToString(); noRekText2.ReadOnly = true; namaText.Text = Nasabah[dgcNasabah.RowNumber,1].ToString(); namaText.ReadOnly = true; alamatText.Text = Nasabah[dgcNasabah.RowNumber,2].ToString(); alamatText.ReadOnly = true; noTelpText.Text = Nasabah[dgcNasabah.RowNumber,3].ToString(); noTelpText.ReadOnly = true; tandaPengenalText.Text = Nasabah[dgcNasabah.RowNumber,4].ToString(); tandaPengenalText.ReadOnly = true; noBukuRekText.Text = Nasabah[dgcNasabah.RowNumber,5].ToString(); noBukuRekText.ReadOnly = true; kantorCabangText.Text = Nasabah[dgcNasabah.RowNumber,6].ToString(); kantorCabangText.ReadOnly = true; saldoSebelumText.Text = Nasabah[dgcNasabah.RowNumber,7].ToString(); saldoSebelumText.ReadOnly = true; conn.Close(); //untuk data Teller conn.Open(); string sql1 = "select * from Teller_bank where nik= '" +nikText.Text+"'"; cmd1 = new OracleCommand(sql1, conn); cmd1.CommandType = CommandType.Text; da1 = new OracleDataAdapter(cmd1); cb1 = new OracleCommandBuilder(da1); ds1 = new DataSet(); da1.Fill(ds1); teller_bank.DataSource = ds1.Tabels[0]; DataGridCell dgcteller_bank = teller_bank.CurrentCell; nikText2.Text = teller_bank[dgcteller_bank.RowNumber,0].ToString(); conn.Close(); }
55
Form Penarikan Tunai ini memerlukan data masukan berupa Jumlah
Nominal Penarikan Tunai. Transaksi Penarikan Tunai akan diproses begitu user
menekan tombol Lanjut. Berikut merupakan perintah yang digunakan ketika user
menekan tombol Lanjut/OK :
private void okButton_Click(object sender, System.EventArgs e) { string PesanError = "Masukan nominal transaksi >= total saldo. Transaksi ditolak. Silahkan isi nominal transaksi kembali..."; try { conn.Open(); // UNTUK PANGGIL PROSEDUR OracleCommand cmd2 = new OracleCommand(); cmd2.Connection = conn;
//Panggil prosedur transaksi_penarikan_tunai cmd2.CommandText = "CC3a_transaksi_penarikan"; cmd2.CommandType = CommandType.StoredProcedure; cmd2.Parameters.Add("p_no_rekening", OracleDbType.Int32).Value = ""+noRekText.Text; cmd2.Parameters.Add("p_nik", OracleDbType.Varchar2).Value = ""+nikText.Text; cmd2.Parameters.Add("p_nominal_debet", OracleDbType.Int64). Value = ""+nominalDebetText.Text; OracleParameter error = cmd2.Parameters.Add("pesan_error",OracleDbType.Varchar2); error.Direction = ParameterDirection.Output; cmd2.ExecuteReader();
this.Hide(); //memanggil FormPenarikan() FormHasilTransaksi_penarikan form1 = new FormHasilTransaksi_penarikan(); form1.noRekText = noRekText; //berikut perintah untuk menampilkan FormHasilTransaksi DialogResult result = form1.ShowDialog();
} catch (OracleException) { MessageBox.Show(PesanError, "Transaksi dibatalkan", MessageBoxButtons.OK, MessageBoxIcon.Information); nominalDebetText.Clear(); }
catch { MessageBox.Show(" Silakan memasukkan jumlah nominal penarikan tunai", "Nominal penarikan tunai diperlukan", MessageBoxButtons.OK, MessageBoxIcon.Information); nominalDebetText.Clear(); }
finally { conn.Close(); } }
56
Ketika tombol Lanjut/OK ditekan, terdapat 3 parameter variable yang
dipassingkan kedalam sebuah procedure bernama cc3a_transaksi_penarikan, yaitu
p_no_rekening, p_nik, dan p_nominal_debet. Terdapat 1 parameter keluaran
berupa pesan_error jika didapati jumlah masukan nilai nominal transaksi
penarikan lebih besar dari total saldo nasabah. Masing-masing parameter diambil
berdasarkan nilai yang direkam/ nilai yang terdapat pada masing-masing textbox
berdasarkan data masukan terdahulu yang dimasukkan oleh user.
ExecuteNonQuery() diperlukan untuk menjalankan procedure jika result setnya
lebih besar dari 1. Ketika procedure dipanggil dan dijalankan, form ini kemudian
ditutup dan menuju form berikutnya yaitu Form Hasil Transaksi Penarikan.
Berikut merupakan procedure penarikan tunai menggunakan PL/SQL:
create or replace procedure CC3a_transaksi_penarikan ( p_no_rekening in nasabah.no_rekening%type, p_nik in teller_bank.nik%type, p_nominal_debet in transaksi.nominal_debet%type, pesan_error out varchar2 ) -- procedure CC3a_transaksi_penarikan untuk mempresentasikan concurrency control menggunakan select for update as p_total_saldo nasabah.total_saldo%type; begin -- untuk melihat total_saldo, dengan maksud mengunci total_saldo nasabah untuk menjamin konsistensi data select total_saldo into p_total_saldo from nasabah where no_rekening = p_no_rekening for update; if p_nominal_debet >= p_total_saldo then pesan_error := 'transaksi gagal'; rollback; end if; user_lock.sleep(1000); p_total_saldo := p_total_saldo - p_nominal_debet; -- untuk meng-update total_saldo dalam tabel nasabah update nasabah set total_saldo = p_total_saldo where no_rekening = p_no_rekening;
57
-- untuk meng-insert transaksi yang berlangsung insert into transaksi (id_transaksi, no_rekening, nik, id_jenis_transaksi, waktu, nominal_debet, nominal_kredit) values (id_transaksi_seq.nextval, p_no_rekening, p_nik, 1, sysdate, p_nominal_debet, 0); commit; end CC3a_transaksi_penarikan;
Procedure bernama cc3a_transaksi_penarikan ini memiliki 3 parameter
masukan, yaitu p_no_rekening, p_nik dan p_nominal_debet, dan 1 parameter
keluaran berupa pesan_error. Untuk menjalankan konsistensi baca dalam level
baca, maka teknik penanganan concurrency control dalam transaksi ini dengan
menggunakan statement SELECT … FROM tabel … FOR UPDATE. Statement
ini dapat menjaga data yang dibaca agar tidak diubah selama proses pembacaan.
Hal ini digunakan untuk menjamin bahwa data tidak diubah selama proses
pembacaan karena sebuah Exclusive row-locks diberlakukan pada baris yang
dimaksud. Perintah ini juga mengandung row share lock mode pada tabel
Nasabah.
Perintah user_lock.Sleep(1000); merupakan sebuah “sleep” procedure
atau dapat dikatakan sebuah waktu tunda/ delay yang dibutuhkan dalam aplikasi.
Dalam perintah ini waktu tunda diset selama 10 detik, dengan maksud agar
beberapa transaksi dapat dijalankan dalam satu periodic waktu atau dengan kata
lain, transaksi sengaja ditabrakkan antara transaksi yang satu dengan yang lainnya
untuk memperlihatkan bagaimana concurrency control dapat tetap menjaga data
tetap konsisten atau tidak. Agar perintah ini dapat digunakan, diperlukan log in
sebagai SYS terlebih dahulu, kemudian menjalankan userlock.sql yang terdapat
dalam direktori $ORACLE_HOME/rdbms/admin.
58
4.4.5. User interface Form Transaksi Penyetoran Tunai
Gambar 4.8 merupakan gambar user interface Form Transaksi Penyetoran
Tunai untuk aplikasi tanpa concurrency control.
Gambar 4.8 Form Transaksi Penyetoran Tunai untuk Aplikasi Tanpa
Concurrency Control
59
Gambar 4.9 merupakan gambar user interface Form Transaksi Penyetoran
Tunai untuk aplikasi dengan concurrency control.
Gambar 4.9 Form Transaksi Penyetoran Tunai untuk Aplikasi Dengan
Concurrency control
Form ini berisikan keluaran data nasabah yang disimpan dalam tabel
nasabah dalam database berdasarkan data masukan dalam Form Menu Utama
berupa no rekening nasabah. Berikut merupakan perintah ketika Form ini pertama
kali dipanggil :
60
private oid FormPenyetoran_Load(object sender, System.EventArgs e) v { conn.Open(); string sql = "select * from Nasabah where No_rekening= '" +noRekText.Text+"'"; cmd = new OracleCommand(sql, conn); cmd.CommandType = CommandType.Text; da = new OracleDataAdapter(cmd); cb = new OracleCommandBuilder(da); ds = new DataSet(); da.Fill(ds); Nasabah.DataSource = ds.Tabels[0]; DataGridCell dgcNasabah = Nasabah.CurrentCell; noRekText2.Text = Nasabah[dgcNasabah.RowNumber,0].ToString(); noRekText2.ReadOnly = true; namaText.Text = Nasabah[dgcNasabah.RowNumber,1].ToString(); namaText.ReadOnly = true; alamatText.Text = Nasabah[dgcNasabah.RowNumber,2].ToString(); alamatText.ReadOnly = true; noTelpText.Text = Nasabah[dgcNasabah.RowNumber,3].ToString(); noTelpText.ReadOnly = true; tandaPengenalText.Text = Nasabah[dgcNasabah.RowNumber,4].ToString(); tandaPengenalText.ReadOnly = true; noBukuRekText.Text = Nasabah[dgcNasabah.RowNumber,5].ToString(); noBukuRekText.ReadOnly = true; kantorCabangText.Text = Nasabah[dgcNasabah.RowNumber,6].ToString(); kantorCabangText.ReadOnly = true; saldoSebelumText.Text = Nasabah[dgcNasabah.RowNumber,7].ToString(); saldoSebelumText.ReadOnly = true; conn.Close(); //untuk data Teller conn.Open(); string sql1 = "select * from Teller_bank where nik= '" +nikText.Text+"'";
cmd1 = new OracleCommand(sql1, conn); cmd1.CommandType = CommandType.Text; da1 = new OracleDataAdapter(cmd1); cb1 = new OracleCommandBuilder(da1); ds1 = new DataSet(); da1.Fill(ds1); teller_bank.DataSource = ds1.Tabels[0]; DataGridCell dgcteller_bank = teller_bank.CurrentCell;
nikText2.Text = teller_bank[dgcteller_bank.RowNumber,0].ToString(); conn.Close(); }
61
Form Penyetoran Tunai ini memerlukan data masukan berupa Jumlah
Nominal Penyetoran Tunai. Transaksi Penyetoran Tunai akan diproses begitu user
menekan tombol Lanjut. Berikut merupakan perintah yang digunakan ketika user
menekan tombol Lanjut/OK :
private void okButton_Click(object sender, System.EventArgs e) {
try { conn.Open(); // UNTUK PANGGIL PROSEDUR OracleCommand cmd2 = new OracleCommand(); cmd2.Connection = conn;
//Panggil prosedur transaksi penyetoran dengan Concurrency control cmd2.CommandText = "cc3d_transaksi_penyetoran"; cmd2.CommandType = CommandType.StoredProcedure;
cmd2.Parameters.Add("p_no_rekening", OracleDbType.Int32).Value = ""+noRekText.Text;
cmd2.Parameters.Add("p_nik", OracleDbType.Varchar2).Value = ""+nikText.Text;
cmd2.Parameters.Add("p_nominal_kredit", OracleDbType.Int64). Value =""+nominalKreditText.Text;
//kalau result setnya > 1, pake ExecuteNonQuery()
//kalau result setnya = satu, pake ExecuteReader() //Krn result setnya > 1, maka: cmd2.ExecuteNonQuery(); this.Hide(); //memanggil FormPenyetoran() FormHasilTransaksi_penyetoran form1 = new FormHasilTransaksi_penyetoran(); form1.noRekText = noRekText; //berikut perintah untuk menampilkan FormPenyetoran DialogResult result = form1.ShowDialog(); }
catch (OracleException ex) { MessageBox.Show(ex.ToString()); }
catch { MessageBox.Show(" Silakan memasukkan jumlah nominal penyetoran tunai", "Nominal penyetoran tunai diperlukan", MessageBoxButtons.OK, MessageBoxIcon.Information); nominalKreditText.Clear(); }
finally { conn.Close(); } }
62
Ketika tombol Lanjut/OK ditekan, terdapat 3 parameter variable yang
dipassingkan kedalam sebuah procedure bernama cc3d_transaksi_penyetoran. 3
parameter tersebut yaitu p_no_rekening, p_nik, dan p_nominal_kredit. Masing-
masing parameter diambil berdasarkan nilai yang direkam/ nilai yang terdapat
pada masing-masing textbox berdasarkan data masukan terdahulu yang
dimasukkan oleh user. ExecuteNonQuery() diperlukan untuk menjalankan
procedure jika result setnya lebih besar dari 1. Ketika procedure dipanggil dan
dijalankan, form ini kemudian ditutup dan menuju form berikutnya yaitu Form
Hasil Transaksi Penyetoran.
Berikut merupakan procedure penyetoran tunai menggunakan PL/SQL:
create or replace procedure CC3d_transaksi_penyetoran ( p_no_rekening in nasabah.no_rekening%type, p_nik in teller_bank.nik%type, p_nominal_kredit in transaksi.nominal_kredit%type ) -- procedure cc3d_transaksi_penyetoran menggunakan update diri sendiri sebelum membaca total_rekening nasabah as p_total_saldo nasabah.total_saldo%type; begin update nasabah set total_saldo=total_saldo where no_rekening = p_no_rekening; select total_saldo into p_total_saldo from nasabah where no_rekening = p_no_rekening; user_lock.sleep(1000); p_total_saldo := p_total_saldo + p_nominal_kredit; update nasabah set total_saldo = p_total_saldo where no_rekening = p_no_rekening; insert into transaksi (id_transaksi, no_rekening, nik, id_jenis_transaksi, waktu, nominal_debet, nominal_kredit) values (id_transaksi_seq.nextval, p_no_rekening, p_nik, 2, sysdate, 0, p_nominal_kredit); commit; end CC3d_transaksi_penyetoran;
63
Procedure bernama cc3d_transaksi_penyetoran ini memiliki 3 parameter
masukan, yaitu p_no_rekening, p_nik dan p_nominal_kredit. Untuk menjalankan
konsistensi baca dalam level baca, maka teknik penanganan concurrency control
dalam transaksi ini dengan menggunakan statement UPDATE pada diri sendiri
sebelum melakukan statement SELECT. Statement ini dapat menjaga data yang
dibaca agar tidak diubah selama proses pembacaan. Hal ini digunakan untuk
menjamin bahwa data tidak diubah selama proses pembacaan karena sebuah
Exclusive row-locks diberlakukan pada baris yang dimaksud. Perintah ini juga
mengandung row-exclusive mode lock pada tabel Nasabah.
64
4.4.6. User interface Form Transaksi Transfer Saldo
Gambar 4.10 merupakan gambar user interface Form Transaksi Transfer
Saldo untuk aplikasi tanpa concurrency control.
Gambar 4.10 Form Transaksi Transfer Saldo untuk Aplikasi Tanpa
Concurrency control
65
Gambar 4.11 merupakan gambar user interface Form Transaksi Transfer
Saldo untuk aplikasi dengan concurrency control.
Gambar 4.11 Form Transaksi Transfer Saldo untuk Aplikasi Dengan
Concurrency control.
Form Transfer Saldo ini berisikan keluaran data nasabah yang disimpan
dalam tabel nasabah dalam database berdasarkan data masukan dalam Form Menu
Utama berupa No Rekening nasabah. Berikut merupakan perintah ketika form ini
dipanggil :
66
private void FormTransferSaldo1_Load(object sender, System.EventArgs e) { conn.Open(); //noRekText.Enabled=false; string sql = "select * from Nasabah where No_rekening= '" +noRekText.Text+"'"; cmd = new OracleCommand(sql, conn); cmd.CommandType = CommandType.Text; da = new OracleDataAdapter(cmd); cb = new OracleCommandBuilder(da); ds = new DataSet(); da.Fill(ds); Nasabah.DataSource = ds.Tabels[0]; DataGridCell dgcNasabah = Nasabah.CurrentCell; noRekText2.Text = Nasabah[dgcNasabah.RowNumber,0].ToString(); noRekText2.ReadOnly = true; namaText.Text = Nasabah[dgcNasabah.RowNumber,1].ToString(); namaText.ReadOnly = true; alamatText.Text = Nasabah[dgcNasabah.RowNumber,2].ToString(); alamatText.ReadOnly = true; noTelpText.Text = Nasabah[dgcNasabah.RowNumber,3].ToString(); noTelpText.ReadOnly = true; tandaPengenalText.Text = Nasabah[dgcNasabah.RowNumber,4].ToString(); tandaPengenalText.ReadOnly = true; noBukuRekText.Text = Nasabah[dgcNasabah.RowNumber,5].ToString(); noBukuRekText.ReadOnly = true; kantorCabangText.Text = Nasabah[dgcNasabah.RowNumber,6].ToString(); kantorCabangText.ReadOnly = true; saldoSebelumText.Text = Nasabah[dgcNasabah.RowNumber,7].ToString(); saldoSebelumText.ReadOnly = true; conn.Close(); }
Form ini memerlukan data masukan berupa Jumlah Nominal Transfer
Saldo dan No Rekening Nasabah Tujuan. Transaksi Transfer Saldo akan diproses
begitu user menekan tombol Lanjut. Berikut merupakan perintah yang digunakan
ketika user menekan tombol Lanjut/OK :
67
private void okButton_Click(object sender, System.EventArgs e) { string PesanError = "Masukan nominal transaksi >= total saldo. Transaksi ditolak. Silahkan isi nominal transaksi kembali..."; try { conn.Open(); if (noRekTujuanText1.Text == noRekText.Text) { noRekTujuanText1.Clear(); MessageBox.Show("No Rekening tujuan harus berbeda dengan No Rekening nasabah"); noRekTujuanText1.Focus(); } string query = "Select * from Nasabah Where No_Rekening = '" +noRekTujuanText.Text.Trim()+"'"; OracleCommand comd = new OracleCommand(query,conn); OracleDataReader reader = comd.ExecuteReader(); if(reader.HasRows) { // UNTUK PANGGIL PROSEDUR OracleCommand cmd2 = new OracleCommand(); cmd2.Connection = conn; //Panggil prosedur transaksi transfer saldo dengan concurrency control cmd2.CommandText = "CC3b_transfer_saldo"; cmd2.CommandType = CommandType.StoredProcedure; cmd2.Parameters.Add("p_no_rekening", OracleDbType.Int32).Value = ""+noRekText.Text; cmd2.Parameters.Add("p_nik", OracleDbType.Varchar2).Value = ""+nikText.Text; cmd2.Parameters.Add("p_nominal_debet", OracleDbType.Int64). Value =""+nominalDebetText.Text; cmd2.Parameters. Add("p_no_rekening_tujuan", OracleDbType.Int32). Value = ""+noRekTujuanText.Text; OracleParameter error = cmd2.Parameters.Add("pesan_error",OracleDbType.Varchar2); error.Direction = ParameterDirection.Output; //kalau result setnya > 1, pake ExecuteNonQuery() //kalau result setnya = satu, pake ExecuteReader() //Krn result setnya > 1, maka: cmd2.ExecuteNonQuery(); this.Hide(); //memanggil FormHasilTransaksi_trans_sal FormHasilTransaksi_trans_sal form1 = new FormHasilTransaksi_trans_sal(); form1.noRekText = noRekText; form1.noRekTujuanText = noRekTujuanText; //berikut perintah untuk menampilkan FormPenarikan DialogResult result = form1.ShowDialog(); }
68
else { noRekTujuanText1.Clear(); MessageBox.Show("No Rekening tidak ada, masukan salah"); noRekTujuanText1.Focus(); } } catch (OracleException) { MessageBox.Show(PesanError, "Transaksi dibatalkan", MessageBoxButtons.OK, MessageBoxIcon.Information); nominalDebetText.Clear(); } catch { MessageBox.Show(" Silakan memasukkan jumlah nominal penyetoran tunai", "Nominal penyetoran tunai diperlukan", MessageBoxButtons.OK, MessageBoxIcon.Information); nominalDebetText.Clear(); } finally { conn.Close(); } }
Ketika tombol Lanjut/OK ditekan, terdapat 4 parameter variable yang
dipassingkan kedalam sebuah procedure bernama cc3b_transfer_saldo, yaitu
p_no_rekening, p_nik, dan p_nominal_debet, p_no_rekening_tujuan beserta 1
parameter output pesan_error. Masing-masing parameter diambil berdasarkan
nilai yang direkam/ nilai yang terdapat pada masing-masing textbox berdasarkan
data masukan terdahulu yang dimasukkan oleh user. ExecuteNonQuery()
diperlukan untuk menjalankan procedure jika result setnya lebih besar dari 1.
Ketika procedure dipanggil dan dijalankan, form ini kemudian ditutup dan menuju
form berikutnya yaitu Form Hasil Transaksi Transfer Saldo. Berikut merupakan
procedure cc3b_transfer_saldo dalam PL/SQL:
69
create or replace procedure CC3b_transfer_saldo ( p_no_rekening in nasabah.no_rekening%type, p_nik in teller_bank.nik%type, p_nominal_debet in transaksi.nominal_debet%type, p_no_rekening_tujuan in nasabah.no_rekening%type, pesan_error out varchar2 ) -- procedure cc3b_transfer_saldo mengunakan isolation level serializabe as p_id_transaksi transaksi.id_transaksi%type; p_total_saldo nasabah.total_saldo%type; p_nominal_kredit transaksi.nominal_kredit%type := p_nominal_debet; pesan_concurrency exception; pragma exception_init (pesan_concurrency,-08177); begin set transaction isolation level serializable; select total_saldo into p_total_saldo from nasabah where no_rekening = p_no_rekening; if p_nominal_debet >= p_total_saldo then pesan_error := 'transaksi gagal'; rollback; end if; user_lock.sleep(1000); p_total_saldo := p_total_saldo - p_nominal_debet; update nasabah set total_saldo = p_total_saldo where no_rekening = p_no_rekening; -- untuk men-kredit atau menambah total_saldo nasabah tujuan select total_saldo into p_total_saldo from nasabah where no_rekening = p_no_rekening_tujuan; p_total_saldo := p_total_saldo + p_nominal_kredit; update nasabah set total_saldo = p_total_saldo where no_rekening = p_no_rekening_tujuan; -- insert ke tabel transaksi insert into transaksi (id_transaksi, no_rekening, nik, id_jenis_transaksi, waktu, nominal_debet, nominal_kredit) values (id_transaksi_seq.nextval, p_no_rekening, p_nik, 3, sysdate, p_nominal_debet, p_nominal_kredit); commit; exception when pesan_concurrency then rollback; CC3b_transfer_saldo(p_no_rekening,p_nik,p_nominal_debet,p_no_rekening_tujuan,pesan_error); end CC3b_transfer_saldo;
70
Procedure bernama cc3b_transfer_saldo ini memiliki 4 parameter
masukan, yaitu p_no_rekening, p_nik, p_nominal_debet dan
p_no_rekening_tujuan beserta 1 parameter keluaran pesan_error. Untuk
menjalankan konsistensi, maka teknik penanganan concurrency control dalam
transaksi ini dengan menggunakan perintah SET TRANSACTION ISOLATION
LEVEL SERIALIZABLE. Salah satu jenis isolasi transaksi ini sangat efektif
untuk menjaga kekonsistenan data dalam level transaksi. Hal ini terjadi karena
isolation level jenis ini hanya melihat data yang berubah dan telah commit pada
saat transaksi dimulai, beserta seluruh perubahan yang dibuat oleh transaksi ini.
Namun, transaksi yang diset isolation level jenis ini mengembalikan sebuah error
ketika transaksi tersebut berjalan, kemudian mencoba untuk mengubah (UPDATE
atau DELETE) data yang sudah dimodifikasi oleh sebuah transaksi yang commit
setelah transaksi serializable ini mulai. Error yang akan muncul :
ORA – 08177 : Cannot serialize access for this transaction
Untuk itu, dalam procedure cc3b_transfer_saldo dimasukkan beberapa aksi yang
dapat dilakukan untuk mengatasi error yang ada, seperti berikut :
1. Menangkap pesan error dengan sebuah exception yang telah
dideklarasikan terlebih dahulu.
2. Me-rollback transaksi
3. Menjalankan kembali transaksi dengan cara memanggil diri sendiri.
71
4.4.7. User interface Form Transaksi Total Saldo
Gambar 4.12 merupakan gambar user interface Form Transaksi Total
Saldo untuk aplikasi tanpa concurrency control.
Gambar 4.12 Form Transaksi Total Saldo untuk Aplikasi Tanpa
Concurrency control
Gambar 4.13 merupakan gambar user interface Form Transaksi Total
Saldo untuk aplikasi dengan concurrency control.
Gambar 4.13 Form Transaksi Total Saldo untuk Aplikasi Dengan
Concurrency control
72
Transaksi Total Saldo seluruh nasabah dibuat untuk mempresentasikan
masalah inconsistent analysis problem. Transaksi ini akan menambahkan semua
total saldo nasabah yang ada dalam tabel dan memasukkannya dalam variable
nilai_sum. Tombol OK dalam form ini akan memanggil procedure transaksi total
saldo yang memiliki 1 parameter OUT. Berikut merupakan perintah ketika tombol
OK ditekan :
private void okButton_Click(object sender, System.EventArgs e) { try { conn.Open(); // UNTUK PANGGIL PROSEDUR OracleCommand cmd2 = new OracleCommand(); cmd2.Connection = conn; //Panggil prosedur transaksi jumlah total saldo dengan concurrency control cmd2.CommandText = "CC3b_jum_tot_sal2"; cmd2.CommandType = CommandType.StoredProcedure; OracleParameter sumParm = cmd2.Parameters.Add("nilai_sum",OracleDbType.Int64); sumParm.Direction = ParameterDirection.Output;
//conn.Open(); OracleDataReader sumReader = cmd2.ExecuteReader();
this.Hide(); //memanggil FormHasilTransaksi_tot_sal() FormHasilTransaksi_tot_sal form1 = new FormHasilTransaksi_tot_sal(); form1.setTotSaldo(cmd2.Parameters["nilai_sum"].Value.ToString()); //berikut perintah untuk menampilkan FormHasilTransaksi_tot_sal
form1.Show(); form1.p_jum_tot_saldo.ReadOnly = true; //form1.nilaiSum= nilaiSum;
}
catch (OracleException ex) {
MessageBox.Show(ex.ToString()); }
catch (Exception e1) {
MessageBox.Show(e1.ToString()); }
finally { conn.Close();
} }
73
Berikut merupakan procedure cc3b_jum_tot_sal2 dalam PL/SQL :
create or replace procedure cc3b_jum_tot_sal2 ( nilai_sum out number ) as -- read consistency with isolation level serializable jum_tot_saldo number; p_no_rekening nasabah.no_rekening%type; p_tot_saldo nasabah.total_saldo%type; p_jum_nasabah number; pesan_concurrency exception; pragma exception_init (pesan_concurrency,-08177); begin set transaction isolation level serializable; jum_tot_saldo := 0; select count(no_rekening) into p_jum_nasabah from nasabah; for i in 1..p_jum_nasabah loop -- select id_nasabah into p_id_nasabah from nasabah where id_nasabah = i; select total_saldo into p_tot_saldo from nasabah where id_nasabah = i; if i=1 then user_lock.Sleep(1000); end if; jum_tot_saldo := jum_tot_saldo + p_tot_saldo; -- i := i+1; end loop; nilai_sum := jum_tot_saldo; dbms_output.put_line(' nilai variabel jum_tot_saldo '||nilai_sum); select sum(total_saldo) into jum_tot_saldo from nasabah; dbms_output.put_line(' nilai jumlah total saldo seluruh nasabah sebenarnya : '||jum_tot_saldo); commit; exception when pesan_concurrency then rollback; cc3b_jum_tot_sal2(nilai_sum); end cc3b_jum_tot_sal2;
Procedure ini memiliki 1 parameter OUT, yaitu nilai_sum. Untuk
menjalankan konsistensi, maka teknik penanganan concurrency control dalam
transaksi ini dengan menggunakan perintah SET TRANSACTION ISOLATION
LEVEL SERIALIZABLE. Jenis masalah inconsistent analysis problem dapat
ditangani dengan jenis isolation level ini. Terdapat variable jum_tot_saldo yang
74
berfungsi sebagai variable penampung jumlah total saldo dari setiap
nasabah. Terdapat looping menggunakan perintah FOR untuk merecord satu-
persatu total_saldo nasabah kemudian memasukkannya dalam variable
jum_tot_saldo. Waktu delay diberikan ketika perintah FOR melakukan looping
untuk pertama kalinya, dengan mengakses nasabah dengan id_nasabah = 1 dan
berakhir sesuai pada nasabah terakhir dengan id_nasabah = p_jum_nasabah.
Selanjutnya, nilai yang ada dalam jum_tot_saldo kemudian dimasukkan dalam
nilai_sum dan digunakan sebagai parameter OUT untuk procedure ini.
4.4.8. User interface Form Hasil Transaksi Penarikan Tunai
Gambar 4.14 merupakan gambar user interface Form Hasil Transaksi
Penarikan untuk aplikasi tanpa concurrency control
Gambar 4.14 Form Hasil Transaksi Penarikan Tunai untuk Aplikasi Tanpa
Concurrency control
75
Gambar 4.15 merupakan gambar user interface Form Hasil Transaksi
Penarikan untuk aplikasi dengan concurrency control
Gambar 4.15 Form Hasil Transaksi Penarikan Tunai untuk Aplikasi Dengan
Concurrency control
Form ini memperlihatkan hasil dari transaksi penarikan tunai. Form ini
membaca data total_saldo dalam tabel nasabah yang melakukan transaksi, untuk
menampung hasil dari transaksi penarikan tunai..
Berikut merupakan perintah pada saat pemanggilan Form Hasil Transaksi
Penarikan Tunai:
76
private void FormHasilTransaksi_Load(object sender, System.EventArgs e) { // Untuk data nasabah ybs conn.Open(); string sql = "select * from Nasabah where No_rekening= '" +noRekText.Text+"'"; cmd = new OracleCommand(sql, conn); cmd.CommandType = CommandType.Text; da = new OracleDataAdapter(cmd); cb = new OracleCommandBuilder(da); ds = new DataSet(); da.Fill(ds); Nasabah.DataSource = ds.Tabels[0]; DataGridCell dgcNasabah = Nasabah.CurrentCell; jumlahSaldoTextBox.Text = Nasabah[dgcNasabah.RowNumber,7].ToString(); jumlahSaldoTextBox.ReadOnly = true; hasilTransaksiTextBox.Text = "Berhasil"; hasilTransaksiTextBox.ReadOnly = true; conn.Close(); }
4.4.9. User interface Form Hasil Transaksi Penyetoran Tunai
Gambar 4.16 merupakan gambar user interface Form Hasil Transaksi
Penyetoran untuk aplikasi tanpa concurrency control
Gambar 4.16 Form Hasil Transaksi Penyetoran Tunai untuk Aplikasi
Tanpa Concurrency control
77
Gambar 4.17 merupakan gambar user interface Form Hasil
Transaksi Penyetoran untuk aplikasi dengan concurrency control
Gambar 4.17 Form Hasil Transaksi Penyetoran Tunai untuk Aplikasi
Dengan Concurreny Control
Form ini memperlihatkan hasil dari transaksi penyetoran tunai. Form ini
membaca data total_saldo dalam tabel nasabah yang melakukan transaksi, untuk
menampung hasil dari transaksi penyetoran tunai.
Berikut merupakan perintah pada saat pemanggilan Form Hasil Transaksi
Penyetoran Tunai:
78
private void FormHasilTransaksi_penyetoran_Load(object sender, System.EventArgs e) { // Untuk data nasabah ybs conn.Open(); string sql = "select * from Nasabah where No_rekening= '" +noRekText.Text+"'"; cmd = new OracleCommand(sql, conn); cmd.CommandType = CommandType.Text; da = new OracleDataAdapter(cmd); cb = new OracleCommandBuilder(da); ds = new DataSet(); da.Fill(ds); Nasabah.DataSource = ds.Tabels[0]; DataGridCell dgcNasabah = Nasabah.CurrentCell; jumlahSaldoTextBox.Text = Nasabah[dgcNasabah.RowNumber,7].ToString(); jumlahSaldoTextBox.ReadOnly = true; hasilTransaksiTextBox.Text = "Berhasil"; hasilTransaksiTextBox.ReadOnly = true; conn.Close(); }
4.4.10. User interface Form Hasil Transaksi Transfer Saldo
Gambar 4.18 merupakan gambar user interface Form Hasil Transaksi
Transfer Saldo untuk aplikasi tanpa concurrency control
Gambar 4.18 Form Hasil Transaksi Transfer Saldo Tanpa Concurrency control
79
Gambar 4.19 merupakan gambar user interface Form Hasil Transaksi
Transfer Saldo untuk aplikasi dengan concurrency control
Gambar 4.19 Form Hasil Transaksi Transfer Saldo Dengan Concurrency control
Form ini memperlihatkan hasil dari transaksi transfer saldo. Form ini
membaca data total_saldo dalam tabel nasabah yang melakukan transaksi, untuk
menampung hasil dari transaksi transfer saldo dan juga menampilkan total saldo
rekeining nasabah tujuan setelah melakukan transaksi.
Berikut merupakan perintah pada saat pemanggilan Form Hasil Transaksi
Transfer Saldo:
80
private void FormHasilTransaksi_trans_sal_Load(object sender, System.EventArgs e) { // Untuk data nasabah ybs conn.Open(); string sql = "select * from Nasabah where No_rekening= '" +noRekText.Text+"'"; string sql2 = "select * from Nasabah where No_rekening= '" +noRekTujuanText.Text+"'"; cmd = new OracleCommand(sql, conn); cmd2 = new OracleCommand(sql2, conn); cmd.CommandType = CommandType.Text; cmd2.CommandType = CommandType.Text; da = new OracleDataAdapter(cmd); da2 = new OracleDataAdapter(cmd2); cb = new OracleCommandBuilder(da); cb2 = new OracleCommandBuilder(da2); ds = new DataSet(); ds2 = new DataSet(); da.Fill(ds); da2.Fill(ds2); Nasabah.DataSource = ds.Tabels[0]; Nasabah2.DataSource = ds2.Tabels[0]; DataGridCell dgcNasabah = Nasabah.CurrentCell; DataGridCell dgcNasabah2 = Nasabah2.CurrentCell; jumlahSaldoTextBox.Text = Nasabah[dgcNasabah.RowNumber,7].ToString(); jumlahSaldoTextBox.ReadOnly = true; saldoNasabahTujuan.Text = Nasabah2[dgcNasabah.RowNumber,7].ToString(); saldoNasabahTujuan.ReadOnly = true; hasilTransaksiTextBox.Text = "Berhasil"; hasilTransaksiTextBox.ReadOnly = true; conn.Close();
81
4.4.11. User interface Form Hasil Transaksi Total Saldo Nasabah
Gambar 4.20 merupakan gambar user interface Form Hasil Transaksi
Total Saldo untuk aplikasi tanpa concurrency control
Gambar 4.20 Form Hasil Transaksi Total Saldo Tanpa Concurrency control
Gambar 4.21 merupakan gambar user interface Form Hasil Transaksi
Total Saldo untuk aplikasi dengan concurrency control
Gambar 4.21 Form Hasil Transaksi Total Saldo Dengan Concurrency control
82
Form ini memperlihatkan hasil dari transaksi total saldo. Form ini
membaca data dari parameter OUT nilai_sum pada procedure transaksi jumlah
total saldo. Kemudian membandingkannya dengan menampilkan jumlah total
saldo nasabah seluruhnya dalam tabel nasabah.
Berikut merupakan perintah pada saat pemanggilan Form Hasil Transaksi
Transfer Saldo:
private void FormHasilTransaksi_tot_sal_Load(object sender, System.EventArgs e) { // Untuk data nasabah ybs conn.Open(); string sql = "select sum(total_saldo) from Nasabah"; cmd = new OracleCommand(sql, conn); cmd.CommandType = CommandType.Text; da = new OracleDataAdapter(cmd); cb = new OracleCommandBuilder(da); ds = new DataSet(); da.Fill(ds); Nasabah.DataSource = ds.Tabels[0]; DataGridCell dgcNasabah = Nasabah.CurrentCell; totalSaldoTextBox.Text = Nasabah[dgcNasabah.RowNumber,0].ToString(); totalSaldoTextBox.ReadOnly = true; hasilTransaksiTextBox.Text = "Berhasil"; hasilTransaksiTextBox.ReadOnly = true; conn.Close();
Perintah berikut akan menampilkan nilai sum yang merupakan keluaran dari
parameter output dalam procedure total saldo pada Form Total Saldo ke dalam
sebuah Textbox p_jum_tot_saldo dalam Form Hasil Transaksi Total Saldo.
public void setTotSaldo(string input) { p_jum_tot_saldo.Text = input; }
83
BAB V
ANALISA HASIL
5.1 Pengujian Aplikasi
5.1.1 Pengujian Aplikasi Tanpa Menggunakan Concurrency control
Pengujian terhadap aplikasi tanpa menggunakan concurrency control
menggunakan 2 aplikasi tanpa menggunakan concurrency control yang dijalankan
bersama-sama. Aplikasi tanpa concurrency control tersebut masing-masing
memiliki delay waktu selama 10 detik. Dengan adanya delay waktu, maka ke-2
aplikasi yang berjalan dapat dibuat bertabrakan. Delay waktu ditentukan dalam
setiap procedure yang digunakan oleh masing-masing transaksi. Berikut
merupakan perintah delay waktu yang diset dalam setiap procedure yang
digunakan dalam aplikasi:
user_lock.sleep(1000);
Pengujian terhadap ke-2 aplikasi yang berjalan secara bersamaan
(bertubrukan) tanpa menggunakan concurrency control ini akan
mempresentasikan 2 masalah utama yang dapat terjadi, yaitu :
1. Masalah hilangnya data yang diubah (lost of update).
Untuk mempresentasikan masalah ini, transaksi penarikan tunai dan
transaksi penyetoran tunai yang digunakan.
2. Masalah analisa yang tidak konsisten (the inconsistent analysis
problem).
84
Untuk mempresentasikan masalah ini, transaksi transfer saldo dan
transaksi total saldo seluruh nasabah yang digunakan.
5.1.1.1 Pengujian Terhadap Masalah Hilangnya Data yang Diubah ( Lost of
update)
Gambar 5.1 merupakan gambar simulasi 2 transaksi tanpa concurrency
control yaitu transaksi Penarikan Tunai dan Transaksi Penyetoran Tunai
dijalankan secara bersamaan.
Gambar 5.1 Simulasi 2 Transaksi Berjalan Bersamaan untuk Aplikasi Tanpa
Concurrency control – Hilangnya Data Yang Diubah
Menu Penarikan Tunai melakukan transaksi untuk nasabah dengan no
rekening 333. Menu Penyetoran tunai juga melakukan transaksi untuk nasabah
dengan no rekening 333. Tampak bahwa jumlah saldo nasabah adalah Rp.
5400000. Menu Penyetoran tunai memasukkan nominal transaksi sebesar Rp.
85
200000, sedangkan Menu Penarikan tunai memasukkan nominal transaksi sebesar
Rp. 100000. Kemudian, transaksi sama-sama dieksekusi. Transaksi penyetoran
tunai berjalan terlebih dahulu, kemudian transaksi penarikan tunai berikutnya
Berikut merupakan form Hasil Transaksi masing-masing transaksi.
Gambar 5.2 merupakan gambar simulasi hasil 2 transaksi berjalan tanpa
concurrency control untuk mempresentasikan masalah hilangnya data yang
diubah.
Gambar 5.2 Simulasi Hasil Transaksi 2 Transaksi Berjalan Bersamaan untuk
Aplikasi Tanpa Concurrency control – Hilangnya Data yang Diubah
Transaksi penyetoran tunai lebih dahulu selesai, menampilkan form hasil
transaksi berupa keluaran untuk total saldo untuk nasabah dengan no rekening 333
= Rp.5600000. Kemudian, Transaksi penarikan tunai selesai, menampilkan form
hasil transaksi dengan keluaran untuk total saldo nasabah dengan no rekening 333
= Rp.5300000.
86
Dengan demikian, tampak hilangnya data yang diubah oleh transaksi
penyetoran tunai sebesar Rp. 200000. Karena data total saldo nasabah terakhir
adalah Rp. 5400000 + Rp. 200000 – Rp. 100000 = Rp. 5500000.
Berikut merupakan PL/SQL dari transaksi penarikan tunai tanpa
concurrency control :
create or replace procedure tanpa_CC3_transaksi_penarikan ( p_no_rekening in nasabah.no_rekening%type, p_nik in teller_bank.nik%type, p_nominal_debet in transaksi.nominal_debet%type, pesan_error out varchar2 ) as -- p_id_transaksi transaksi.id_transaksi%type; p_total_saldo nasabah.total_saldo%type; -- p_id_jenis_transaksi jenis_transaksi.id_jenis_transaksi%type; begin select total_saldo into p_total_saldo from nasabah where no_rekening = p_no_rekening; if p_nominal_debet >= p_total_saldo then pesan_error := 'transaksi gagal'; rollback; end if; user_lock.sleep(1000); p_total_saldo := p_total_saldo - p_nominal_debet; update nasabah set total_saldo = p_total_saldo where no_rekening = p_no_rekening; insert into transaksi (id_transaksi, no_rekening, nik, id_jenis_transaksi, waktu, nominal_debet, nominal_kredit) values (id_transaksi_seq.nextval, p_no_rekening, p_nik, 1, sysdate, p_nominal_debet, 0); -- select id_transaksi_seq.currval into p_id_transaksi from dual; commit; end tanpa_CC3_transaksi_penarikan;
87
Berikut merupakan PL/SQL dari transaksi penyetoran tunai tanpa concurrency
control :
create or replace procedure tanpa_CC3_transaksi_penyetoran ( p_no_rekening in nasabah.no_rekening%type, p_nik in teller_bank.nik%type, p_nominal_kredit in transaksi.nominal_kredit%type ) as p_id_transaksi transaksi.id_transaksi%type; p_total_saldo nasabah.total_saldo%type; begin select total_saldo into p_total_saldo from nasabah where no_rekening = p_no_rekening; user_lock.sleep(1000); p_total_saldo := p_total_saldo + p_nominal_kredit; update nasabah set total_saldo = p_total_saldo where no_rekening = p_no_rekening; insert into transaksi (id_transaksi, no_rekening, nik, id_jenis_transaksi, waktu, nominal_debet, nominal_kredit) values (id_transaksi_seq.nextval, p_no_rekening, p_nik, 2, sysdate, 0, p_nominal_kredit); commit; end tanpa_CC3_transaksi_penyetoran;
88
Tabel 5.1 berikut merupakan tabel yang menggambarkan proses yang
terjadi pada pengujian aplikasi tanpa menggunakan concurrency control terhadap
masalah hilangnya data yang diubah.
Waktu
Simulasi Aplikasi Tak Ada Concurrency
control (Transaksi
Penyetoran)
Simulasi Aplikasi Tak Ada Concurrency
control (Transaksi Penarikan)
Total Saldo
t1
SELECT total_saldo INTO p_total_saldo FROM nasabah where no_rekening = 333;
5400000
t2 Delay
SELECT total_saldo INTO p_total_saldo FROM nasabah where no_rekening = 333;
5400000
t3
p_total_saldo := p_total_saldo + p_nominal_kredit;
Delay 5400000
t4
update nasabah set total_saldo = p_total_saldo where no_rekening = 333;
p_total_saldo := p_total_saldo - p_nominal_debet;
5600000
t5
update nasabah set total_saldo = p_total_saldo where no_rekening = 333;
5300000
Tabel 5.1 Proses Yang Terjadi Pada Pengujian Aplikasi Tanpa Menggunakan
Concurrency control –
Terhadap Masalah Hilangnya Data Yang Diubah
89
Dari tabel diatas tampak bahwa perubahan terhadap total saldo yang telah
berhasil dilakukan oleh transaksi yang terlebih dahulu terjadi, yaitu transaksi
penyetoran, hilang. Hal ini terjadi karena transaksi kedua, yaitu transaksi
penarikan, diijinkan membaca data total saldo yang akan segera diubah oleh
transaksi pertama, yaitu transaksi penyetoran. Hal ini mengakibatkan transaksi
kedua, yaitu transaksi penarikan tidak melihat perubahan yang telah dilakukan
oleh transaksi pertama, transaksi penyetoran, terhadap total saldo.
5.1.1.2 Pengujian Terhadap Masalah Analisa yang Tidak Konsisten ( The
inconsistent analysis problem)
Gambar 5.3 merupakan gambar simulasi 2 transaksi tanpa concurrency
control yaitu Transaksi Transfer Saldo dan Transaksi Total Saldo Seluruh
Nasabah dijalankan secara bersamaan.
90
Gambar 5.3 Simulasi 2 Transaksi Berjalan Bersamaan untuk Aplikasi Tanpa
Concurrency Control – Masalah Analisa yang Tidak Konsisten
Transaksi jumlah total saldo seluruh nasabah memanggil sebuah procedure
yang memiliki sebuah parameter OUT yaitu nilai_sum. Nilai_sum memuat jumlah
total saldo nasabah seluruhnya dengan cara menjumlahkannya satu-persatu. Pada
Transaksi Transfer Saldo, nasabah dengan no rekening 111 dengan total saldo Rp
6300000 hendak melakukan transfer saldo pada nasabah dengan no rekening 222
sebesar Rp. 100000. Kemudian transaksi sama-sama dieksekusi. Berikut
merupakan form Hasil Transaksi masing-masing transaksi.
91
Gambar 5.4 merupakan gambar simulasi hasil 2 transaksi berjalan tanpa
concurrency control untuk mempresentasikan masalah analisa yang tidak
konsisten.
Gambar 5.4 Simulasi Hasil Transaksi 2 Transaksi Berjalan Bersamaan untuk
Aplikasi Tanpa Concurrency control –
Masalah Analisa yang Tidak Konsisten
Transaksi transfer saldo menampilkan form hasil transaksi berupa keluaran
untuk total saldo untuk nasabah dengan no rekening 111 = Rp.6200000. Transaksi
total saldo seluruh nasabah selesai, menampilkan form hasil transaksi total saldo
seluruh nasabah dengan keluaran yang tidak sama antara variable penampung
jumlah total saldo seluruh nasabah, hasil dari parameter OUT nilai_sum yang
dipassingkan dalam variable p_jum_tot_saldo, dengan jumlah total saldo seluruh
nasabah sebenarnya.
92
Dengan demikian, tampak masalah analisa yang tidak konsisten pada
transaksi total saldo seluruh nasabah, antara data jumlah total saldo pada tabel
nasabah dengan variable yang menyimpan data jumlah total saldo dalam prosedur.
Berikut merupakan PL/SQL dari transaksi total saldo tanpa concurrency
control :
create or replace procedure tanpa_cc3b_jum_tot_sal2 ( nilai_sum out number ) as -- read consistency with isolation level serializable jum_tot_saldo number; p_no_rekening nasabah.no_rekening%type; p_tot_saldo nasabah.total_saldo%type; p_jum_nasabah number; begin jum_tot_saldo := 0; select count(no_rekening) into p_jum_nasabah from nasabah; for i in 1..p_jum_nasabah loop -- select id_nasabah into p_id_nasabah from nasabah where id_nasabah = i; select total_saldo into p_tot_saldo from nasabah where id_nasabah = i; if i=1 then user_lock.Sleep(1000); end if; jum_tot_saldo := jum_tot_saldo + p_tot_saldo; -- i := i+1; end loop; nilai_sum := jum_tot_saldo; dbms_output.put_line(' nilai variabel jum_tot_saldo '||nilai_sum); select sum(total_saldo) into jum_tot_saldo from nasabah; dbms_output.put_line(' nilai jumlah total saldo seluruh nasabah sebenarnya : '||jum_tot_saldo);commit; end tanpa_cc3b_jum_tot_sal2;
Perlu diperhatikan, transaksi total saldo seluruh nasabah yang memanggil
procedure tanpa_cc3b_jum_tot_sal2 bertujuan untuk mempresentasikan masalah
analisa yang tidak konsisten dalam aplikasi untuk multiuser. Oleh karena itu,
dalam procedure tanpa_cc3b_jum_tot_sal2 terdapat perintah untuk melakukan
delay hanya terhadap nasabah dengan id nasabah = 1 atau no rekening = 111. Hal
93
ini bertujuan agar masalah analisa yang tidak konsisten muncul ketika sebuah
transaksi melakukan interfensi terhadap nasabah dengan id nasabah =1 atau no
rekening = 111. Dalam procedure diatas, masalah analisa yang tidak konsisten
tidak akan tampak jika user lain yang yang sedang melaksanakan transaksi lain
melakukan interfensi terhadap nasabah lainnya.
Berikut merupakan PL/SQL dari transaksi transfer saldo tanpa
concurrency control :
create or replace procedure tanpa_CC3_transfer_saldo ( p_no_rekening in nasabah.no_rekening%type, p_nik in teller_bank.nik%type, p_nominal_debet in transaksi.nominal_kredit%type, p_no_rekening_tujuan in nasabah.no_rekening%type, pesan_error out varchar2 ) as p_id_transaksi transaksi.id_transaksi%type; p_total_saldo nasabah.total_saldo%type; p_nominal_kredit transaksi.nominal_kredit%type := p_nominal_debet; begin -- untuk men-debet atau mengurangi nasabah yang melakukan transaksi transfer saldo select total_saldo into p_total_saldo from nasabah where no_rekening = p_no_rekening; if p_nominal_debet >= p_total_saldo then pesan_error := 'transaksi gagal'; rollback; end if; user_lock.sleep(1000); p_total_saldo := p_total_saldo - p_nominal_debet; update nasabah set total_saldo = p_total_saldo where no_rekening = p_no_rekening; -- untuk men-kredit atau menambah total_saldo nasabah tujuan select total_saldo into p_total_saldo from nasabah where no_rekening = p_no_rekening_tujuan; -- user_lock.sleep(1000); p_total_saldo := p_total_saldo + p_nominal_kredit; update nasabah set total_saldo = p_total_saldo where no_rekening = p_no_rekening_tujuan; -- insert ke tabel transaksi insert into transaksi (id_transaksi, no_rekening, nik, id_jenis_transaksi, waktu, nominal_debet, nominal_kredit) values (id_transaksi_seq.nextval, p_no_rekening, p_nik, 3, sysdate, p_nominal_debet, p_nominal_kredit); commit; end tanpa CC3 transfer saldo;
94
Tabel 5.2 berikut merupakan tabel yang menggambarkan proses yang
terjadi pada pengujian aplikasi tanpa menggunakan concurrency control terhadap
masalah analisa yang tidak konsisten.
Waktu
Simulasi Aplikasi Tak
Ada Concurrency
control (Transaksi
Transfer Saldo)
Simulasi Aplikasi Tak
Ada Concurrency
control (Transaksi
Total Saldo)
Total Saldo Nasabah
(No_rekening=111 atau
id_nasabah=1)
Variabel nilai_sum (= jum_tot_saldo)
t1
SELECT total_saldo INTO p_total_saldo FROM nasabah where no_rekening = 111;
6300000
t2 Delay
SELECT total_saldo INTO p_tot_saldo FROM nasabah WHERE id_nasabah =1;
6300000
0
t3
p_total_saldo := p_total_saldo - p_nominal_debet;
Delay 6300000
0
t4
UPDATE nasabah SET total_saldo = p_total_saldo WHERE no_rekening = 111;
jum_tot_saldo := jum_tot_saldo + p_tot_saldo;
6200000
6300000
95
t5
SELECT total_saldo INTO p_total_saldo FROM nasabah where no_rekening = 222;
SELECT total_saldo INTO p_tot_saldo FROM nasabah WHERE id_nasabah = 2;
6200000
6300000
… … … … …
Tabel 5.2 Proses Yang Terjadi Pada Pengujian Aplikasi Tanpa Menggunakan
Concurrency control –
Terhadap Masalah Analisa Yang Tidak Konsisten
Dari tabel diatas tampak variabel nilai_sum atau variabel jum_tot_saldo
yang menjumlahkan semua total saldo dari seluruh nasabah, memiliki hasil yang
tidak konsisten dengan hasil jumlah total saldo seluruh nasabah pada database.
Hal ini dikarenakan pada saat transaksi transfer saldo terjadi, transaksi total saldo
seluruh nasabah menyimpan jumlah total masing-masing total saldo nasabah
dalam variabel nilai_sum, padahal pada saat yang sama transaksi transfer saldo
sedang mengubah nilai dari total saldo nasabah yang sedang melakukan transaksi
transfer saldo. Ketidakkonsistenan terjadi pada saat nilai_sum membaca total
saldo nasabah dengan no rekening = 111 atau id nasabah = 1, serta menampung
total saldo nasabah tersebut yang sedang berubah pada saat yang sama ketika
transaksi transfer saldo mengubah total saldo nasabah yang bersangkutan.
96
5.1.2 Pengujian Aplikasi Dengan Menggunakan Concurrency control
Pengujian terhadap aplikasi dengan menggunakan concurrency control
menggunakan 2 aplikasi dengan menggunakan concurrency control yang
dijalankan bersama-sama. Aplikasi dengan concurrency control tersebut masing-
masing memiliki delay waktu selama 10 detik. Dengan adanya delay waktu, maka
ke-2 aplikasi yang berjalan dapat dibuat bertabrakan.
5.1.2.1 Pengujian Terhadap Masalah Hilangnya Data yang Diubah ( Lost of
update)
Gambar 5.5 merupakan gambar simulasi 2 transaksi dengan concurrency
control yaitu transaksi Penarikan Tunai dan Transaksi Penyetoran Tunai
dijalankan secara bersamaan.
Gambar 5.5 Simulasi 2 Transaksi Berjalan Bersamaan untuk Aplikasi Dengan
Concurrency control – Terhadap Masalah Hilangnya Data Yang Diubah
97
Transaksi Penarikan Tunai melakukan transaksi untuk nasabah dengan no
rekening 333. Transaksi Penyetoran tunai juga melakukan transaksi untuk nasabah
dengan no rekening 333. Tampak bahwa jumlah saldo nasabah adalah Rp.
5300000. Menu Penyetoran tunai memasukkan nominal transaksi sebesar Rp.
200000, sedangkan Menu Penarikan tunai memasukkan nominal transaksi sebesar
Rp. 100000. Kemudian, transaksi sama-sama dieksekusi. Transaksi penyetoran
tunai berjalan terlebih dahulu, kemudian transaksi penarikan tunai berikutnya.
Berikut merupakan form Hasil Transaksi masing-masing transaksi.
Gambar 5.6 merupakan gambar simulasi hasil 2 transaksi berjalan dengan
concurrency control untuk mempresentasikan masalah hilangnya data yang
diubah.
Gambar 5.6 Simulasi Hasil Transaksi 2 Transaksi Berjalan Bersamaan untuk
Aplikasi Dengan Concurrency control –
Terhadap Masalah Hilangnya Data yang Diubah
98
Transaksi penyetoran tunai lebih dahulu selesai, menampilkan form hasil transaksi
berupa keluaran untuk total saldo untuk nasabah dengan no rekening 333 =
Rp.5500000. Kemudian, Transaksi penarikan tunai selesai, menampilkan form
hasil transaksi dengan keluaran untuk total saldo nasabah dengan no rekening 333
= Rp.5400000.
Dengan demikian, tampak bahwa transaksi tidak mengalami masalah
hilangnya data yang diubah.
Berikut merupakan PL/SQL dari transaksi penarikan tunai dengan concurrency
control :
create or replace procedure CC3a_transaksi_penarikan ( p_no_rekening in nasabah.no_rekening%type, p_nik in teller_bank.nik%type, p_nominal_debet in transaksi.nominal_debet%type, pesan_error out varchar2 ) -- procedure CC3a_transaksi_penarikan untuk mempresentasikan concurrency control menggunakan select for update as p_total_saldo nasabah.total_saldo%type; begin -- untuk melihat total_saldo, dengan maksud mengunci total_saldo nasabah untuk menjamin konsistensi data select total_saldo into p_total_saldo from nasabah where no_rekening = p_no_rekening for update; if p_nominal_debet >= p_total_saldo then pesan_error := 'transaksi gagal'; rollback; end if; user_lock.sleep(1000); p_total_saldo := p_total_saldo - p_nominal_debet; -- untuk meng-update total_saldo dalam tabel nasabah update nasabah set total_saldo = p_total_saldo where no_rekening = p_no_rekening;
99
-- untuk meng-insert transaksi yang berlangsung insert into transaksi (id_transaksi, no_rekening, nik, id_jenis_transaksi, waktu, nominal_debet, nominal_kredit) values (id_transaksi_seq.nextval, p_no_rekening, p_nik, 1, sysdate, p_nominal_debet, 0); commit; end CC3a_transaksi_penarikan;
Berikut merupakan PL/SQL dari transaksi penyetoran tunai dengan
concurrency control :
create or replace procedure CC3d_transaksi_penyetoran ( p_no_rekening in nasabah.no_rekening%type, p_nik in teller_bank.nik%type, p_nominal_kredit in transaksi.nominal_kredit%type ) -- procedure cc3d_transaksi_penyetoran menggunakan update diri sendiri sebelm membaca total_rekening nasabah as p_total_saldo nasabah.total_saldo%type; begin update nasabah set total_saldo=total_saldo where no_rekening = p_no_rekening; select total_saldo into p_total_saldo from nasabah where no_rekening = p_no_rekening; user_lock.sleep(1000); p_total_saldo := p_total_saldo + p_nominal_kredit; update nasabah set total_saldo = p_total_saldo where no_rekening = p_no_rekening; insert into transaksi (id_transaksi, no_rekening, nik, id_jenis_transaksi, waktu, nominal_debet, nominal_kredit) values (id_transaksi_seq.nextval, p_no_rekening, p_nik, 2, sysdate, 0, p_nominal_kredit); commit; end CC3d_transaksi_penyetoran;
100
Tabel 5.3 berikut merupakan tabel yang menggambarkan proses yang
terjadi pada pengujian aplikasi dengan menggunakan concurrency control
terhadap masalah hilangnya data yang diubah.
Waktu
Simulasi Aplikasi Concurrency control
(Transaksi Penyetoran)
Simulasi Aplikasi Concurrency control
(Transaksi Penarikan)
Total Saldo
t1
UPDATE nasabah SET total_saldo=total_saldo WHERE no_rekening = p_no_rekening;
5300000
t2
SELECT total_saldo INTO p_total_saldo FROM nasabah where no_rekening = 333;
5300000
t3 Delay
SELECT total_saldo INTO p_total_saldo FROM nasabah where no_rekening = 333 FOR UPDATE;
(WAIT)
5300000
t4
p_total_saldo := p_total_saldo + p_nominal_kredit;
(WAIT) 5300000
t5
UPDATE nasabah SET total_saldo = p_total_saldo WHERE no_rekening = 333;
(WAIT) 5500000
t6
SELECT total_saldo INTO p_total_saldo FROM nasabah where no_rekening = 333 FOR UPDATE;
5500000
t7 Delay 5500000
t8 p_total_saldo := p_total_saldo - p_nominal_debet;
5500000
101
t9
UPDATE nasabah SET total_saldo = p_total_saldo WHERE no_rekening = 333;
5400000
Tabel 5.3 Proses Yang Terjadi Pada Pengujian Aplikasi Dengan Menggunakan
Concurrency control –
Terhadap Masalah Hilangnya Data yang Diubah
Dari tabel diatas tampak bahwa implementasi dengan menggunakan
statement UPDATE terhadap diri sendiri sebelum bermaksud membaca untuk
mengubah sebuah item data, serta statement SELECT … FOR UPDATE,
memberlakukan exclusive row-locks pada sebuah item data. Pembacaan total
saldo oleh transaksi kedua, yaitu transaksi penarikan, ditunda sampai exclusive
row-lock di-unlock, yaitu pada saat transaksi pertama yaitu transaksi penyetoran
selesai melakukan UPDATE terhadap total saldo. Hal ini menyebabkan tidak
adanya masalah hilangnya data yang du-update.
5.1.2.2 Pengujian Terhadap Masalah Analisa yang Tidak Konsisten ( The
inconsistent analysis problem)
Gambar 5.7 merupakan gambar simulasi 2 transaksi dengan concurrency
control yaitu Transaksi Transfer Saldo dan Transaksi Total Saldo Seluruh
Nasabah dijalankan secara bersamaan.
102
Gambar 5.7 Simulasi 2 Transaksi Berjalan Bersamaan untuk Aplikasi Dengan
Concurrency control – Masalah Analisa yang Tidak Konsisten
Transaksi jumlah total saldo seluruh nasabah memanggil sebuah procedure
yang memiliki sebuah parameter OUT yaitu nilai_sum. Nilai_sum memuat jumlah
total saldo nasabah seluruhnya dengan cara menjumlahkannya satu-persatu. Pada
Transaksi Transfer Saldo, nasabah dengan no rekening 111 dengan total saldo Rp
6100000 hendak melakukan transfer saldo pada nasabah dengan no rekening 222
sebesar Rp. 100000. Kemudian transaksi sama-sama dieksekusi. Berikut
merupakan form Hasil Transaksi masing-masing transaksi.
Gambar 5.8 merupakan gambar simulasi hasil 2 transaksi berjalan dengan
concurrency control untuk mempresentasikan masalah analisa yang tidak
konsisten.
103
Gambar 5.8 Simulasi Hasil Transaksi 2 Transaksi Berjalan Bersamaan untuk
Aplikasi Dengan Concurrency control – Masalah Analisa yang Tidak Konsisten
Transaksi transfer saldo menampilkan form hasil transaksi berupa keluaran
untuk total saldo untuk nasabah dengan no rekening 111 = Rp.6000000. Transaksi
total saldo seluruh nasabah selesai, menampilkan form hasil transaksi total saldo
seluruh nasabah dengan keluaran yang sama antara variable penampung jumlah
total saldo seluruh nasabah, hasil dari parameter OUT nilai_sum yang
dipassingkan dalam variable p_jum_tot_saldo, dengan jumlah total saldo seluruh
nasabah sebenarnya.
Dengan demikian, tampak tidak ada masalah analisa yang tidak konsisten
pada transaksi total saldo seluruh nasabah dengan concurrency control, antara
data jumlah total saldo pada tabel nasabah dengan variable yang menyimpan data
jumlah total saldo dalam prosedur.
104
Berikut merupakan PL/SQL dari transaksi total saldo dengan concurrency
control:
create or replace procedure cc3b_jum_tot_sal2 ( nilai_sum out number ) as -- read consistency with isolation level serializable jum_tot_saldo number; p_no_rekening nasabah.no_rekening%type; p_tot_saldo nasabah.total_saldo%type; p_jum_nasabah number; pesan_concurrency exception; pragma exception_init (pesan_concurrency,-08177); begin set transaction isolation level serializable; jum_tot_saldo := 0; select count(no_rekening) into p_jum_nasabah from nasabah; for i in 1..p_jum_nasabah loop select total_saldo into p_tot_saldo from nasabah where id_nasabah = i; if i=1 then user_lock.Sleep(1000); end if; jum_tot_saldo := jum_tot_saldo + p_tot_saldo; end loop; nilai_sum := jum_tot_saldo; dbms_output.put_line(' nilai variabel jum_tot_saldo '||nilai_sum); select sum(total_saldo) into jum_tot_saldo from nasabah; dbms_output.put_line(' nilai jumlah total saldo seluruh nasabah sebenarnya : '||jum_tot_saldo); commit; exception when pesan_concurrency then rollback; cc3b_jum_tot_sal2(nilai_sum);
Perlu diperhatikan, transaksi total saldo seluruh nasabah yang memanggil
procedure cc3b_jum_tot_sal2 bertujuan untuk mempresentasikan aplikasi dengan
penanganan concurrency control dapat mencegah masalah analisa yang tidak
konsisten dalam aplikasi untuk multiuser. Oleh karena itu, dalam procedure
cc3b_jum_tot_sal2 terdapat perintah untuk melakukan delay hanya terhadap
105
nasabah dengan id nasabah = 1 atau no rekening = 111. Hal ini bertujuan agar
masalah analisa yang tidak konsisten sebenarnya dapat muncul ketika sebuah
transaksi melakukan interfensi terhadap nasabah dengan id nasabah =1 atau no
rekening = 111.
Berikut merupakan PL/SQL dari transaksi transfer saldo dengan concurrency
control:
create or replace procedure CC3b_transfer_saldo ( p_no_rekening in nasabah.no_rekening%type, p_nik in teller_bank.nik%type, p_nominal_debet in transaksi.nominal_debet%type, p_no_rekening_tujuan in nasabah.no_rekening%type, pesan_error out varchar2 ) -- procedure cc3b_transfer_saldo mengunakan isolation level serializabe as p_id_transaksi transaksi.id_transaksi%type; p_total_saldo nasabah.total_saldo%type; p_nominal_kredit transaksi.nominal_kredit%type := p_nominal_debet; pesan_concurrency exception; pragma exception_init (pesan_concurrency,-08177); begin set transaction isolation level serializable; select total_saldo into p_total_saldo from nasabah where no_rekening = p_no_rekening; if p_nominal_debet >= p_total_saldo then pesan_error := 'transaksi gagal'; rollback; end if; user_lock.sleep(1000); p_total_saldo := p_total_saldo - p_nominal_debet; update nasabah set total_saldo = p_total_saldo where no_rekening = p_no_rekening; -- untuk men-kredit atau menambah total_saldo nasabah tujuan select total_saldo into p_total_saldo from nasabah where no_rekening = p_no_rekening_tujuan; p_total_saldo := p_total_saldo + p_nominal_kredit; update nasabah set total_saldo = p_total_saldo where no_rekening = p_no_rekening_tujuan; -- insert ke tabel transaksi insert into transaksi (id_transaksi, no_rekening, nik, id_jenis_transaksi, waktu, nominal_debet, nominal_kredit) values (id transaksi seq.nextval, p no rekening, p nik, 3, sysdate, p nominal debet,
106
Tabel 5.4 berikut merupakan tabel yang menggambarkan proses yang terjadi
pada pengujian aplikasi menggunakan concurrency control terhadap masalah
analisa yang tidak konsisten.
Waktu
Simulasi Aplikasi
Concurrency control
(Transaksi Transfer Saldo)
Simulasi Aplikasi
Concurrency control
(Transaksi Total Saldo)
Total Saldo Nasabah
(No_rekening=111 atau
id_nasabah=1)
Variabel nilai_sum (= jum_tot_saldo)
set transaction isolation level serializable;
t1
SELECT total_saldo INTO p_total_saldo FROM nasabah where no_rekening = 111;
set transaction isolation level serializable;
6300000
t2 Delay
SELECT total_saldo INTO p_tot_saldo FROM nasabah WHERE id_nasabah =1;
(WAIT)
6300000
0
t3
p_total_saldo := p_total_saldo - p_nominal_debet;
If id_nasabah = 1 Benar
Delay
6300000
0
commit; exception when pesan_concurrency then rollback; CC3b_transfer_saldo(p_no_rekening,p_nik,p_nominal_debet,p_no_rekening_tujuan,pesan_error); end CC3b_transfer_saldo;
107
t4
UPDATE nasabah SET total_saldo = p_total_saldo WHERE no_rekening = 111;
(WAIT) 6200000
0
t5
SELECT total_saldo INTO p_total_saldo FROM nasabah where no_rekening = 222;
jum_tot_saldo := jum_tot_saldo + p_tot_saldo;
6200000
6200000
t6 p_total_saldo := p_total_saldo + p_nominal_kredit;
SELECT total_saldo INTO p_tot_saldo FROM nasabah WHERE id_nasabah =2;
6200000
6200000
… … … … …
Tabel 5.4 Proses Yang Terjadi Pada Pengujian Aplikasi Menggunakan
Concurrency control –Terhadap Masalah Analisa Yang Tidak Konsisten
Dari tabel diatas tampak bahwa sebuah isolation level SERIALIZABLE
dapat mencegah masalah analisa yang tidak konsisten. Isolation level
SERIALIZABLE dalam transaksi tampak mengijinkan transaksi isolation level
SERIALIZABLE lainnya untuk berjalan bersamaan, namun isolation level
SERIALIZABLE pada transaksi transfer saldo menerapkan row-level locking
pada saat statement UPDATE berusaha untuk mengubah total saldo nasabah. Hal
ini mengakibatkan transaksi total saldo seluruh nasabah yang sedang berusaha
untuk membaca total saldo nasabah dengan id nasabah = 1 untuk menunggu item
data total saldo nasabah dengan id nasabah = 1 atau no rekening = 111 yang
sedang diubah / diblok oleh transaksi transfer saldo. Begitu item data yang di-blok
108
tersebut selesai diubah, transaksi total saldo seluruh nasabah dapat merekam niai
total saldo yang telah diubah dan memasukkannya dalam variable nilai_sum. Hal
ini menjamin kekonsistenan data pada setiap variable yang ada dalam suatu
transaksi sesuai dengan data dalam database.
5.2 Kelebihan dan Kekurangan Sistem
5.2.1 Kelebihan Sistem
Berikut ini adalah beberapa kelebihan dari system :
Sistem dibuat dengan menggunakan beberapa tipe dari concurrency
control pada Oracle, seperti :
- Dengan memanfaatkan salah satu jenis isolation level pada Oracle,
yaitu SERIALIZABLE.
- Dengan memanfaatkan tipe exclusive row lock pada statement:
• SELECT… FOR UPDATE untuk menjamin
kekonsistenan baca pada data yang akan diubah.
• UPDATE terhadap diri sendiri sebelum statement
SELECT data untuk menjamin kekonsistenan baca pada
data yang akan diubah.
Sistem yang dibangun dengan menggunakan concurrency control bebas
dari masalah akses bersama seperti : hilangnya data yang diubah (lost of
update) dan masalah analisa yang tidak konsisten (the inconsistent
analysis problem).
Setiap transaksi yang mengubah data dalam database digunakan dalam
procedure PL/SQL sehingga memudahkan pengembangan aplikasi
109
5.2.2 Kekurangan Sistem
Berikut ini adalah kekurangan dari system :
Sistem hanya berupa simulasi, belum merupakan aplikasi utuh untuk
Teller Bank.
110
BAB VI
PENUTUP
6.1 Kesimpulan
1. Aplikasi dapat mencegah masalah hilangnya data yang diubah (lost of
update) dan juga masalah analisa yang tidak konsisten (the inconsistent
analysis problem).
2. Concurrency control dalam Oracle dapat dicapai dengan beberapa cara,
seperti menggunakan:
- Statement SELECT .. FOR UPDATE
- Isolation level SERIALIZABLE
- Statement UPDATE pada diri sendiri sebelum melakukan proses baca
dengan maksud mengubah data yang dibaca.
6.2 Saran
Aplikasi dapat dikembangkan menjadi aplikasi untuk Teller Bank
111
DAFTAR PUSTAKA
Connolly, T., Begg, C., DATABASE SYSTEM A Pratical Approach To Design, Implementation And Management, Addison Wesley, 2002.
Oracle Database Express Edition 2 Day Plus .NET Developer Guide 10g Release
2 (10.2)
Oracle Database Concept 10g Release 1 (10.1)
Hutabarat, B.L, Pemrograman Oracle PL/SQL, ANDI Yogyakarta, 2002.
Bradley, J., Millspaugh, A., Programming in C#.NET, McGRAW-HILL, 2004.
Budiharto,W., Rahardi, S., APLIKASI DATABASE ORACLE 10g dengan
VB6/VB.NET
Oracle Database 10g: SQL Fundamentals I, ORACLE UNIVERSITY, August
2004
Oracle Database 10g: SQL Fundamentals II, ORACLE UNIVERSITY, August
2004
Oracle 9i : ProgramWith PL/SQL, ORACLE UNIVERSITY, October 2001
LAMPIRAN
Koneksi.cs using Oracle.DataAccess.Client; using Oracle.DataAccess.Types; public class Koneksi { private static string con_str; public Koneksi() { } static Koneksi() { con_str = @"user id=grace;data source=localhost;password=grace"; // Untuk koneksi ke database } public static string CON_STR { get { return con_str; } } public static OracleConnection CON { get { return new OracleConnection(con_str); } } }
MenuUtamaForm.cs using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; //using System.Data.OracleClient; using Oracle.DataAccess.Client; using Oracle.DataAccess.Types; // untuk referensi dataset ds : using System.Data; namespace _051106 { /// <summary> /// Summary description for MenuUtamaForm. /// </summary> public class MenuUtamaForm : System.Windows.Forms.Form { private System.Windows.Forms.Label label1; private System.Windows.Forms.RadioButton penarikanRB; private System.Windows.Forms.RadioButton penyetoranRB; private System.Windows.Forms.RadioButton transferSaldoRB; private System.Windows.Forms.RadioButton totalSaldoRB; private System.Windows.Forms.GroupBox groupBox1;
private OracleConnection conn = Koneksi.CON; public System.Windows.Forms.TextBox noRekText; public System.Windows.Forms.TextBox idJenisTransaksiText; private OracleDataAdapter da; private OracleCommandBuilder cb; private DataSet ds; private System.Windows.Forms.DataGrid Jenis_transaksi; private System.Windows.Forms.Label idJenisTransaksiLabel; public System.Windows.Forms.TextBox nikText; private System.Windows.Forms.DataGrid teller_bank; private OracleCommand cmd1; private OracleDataAdapter da1; private OracleCommandBuilder cb1; private DataSet ds1; private System.Windows.Forms.TextBox nikText2; private System.Windows.Forms.PictureBox pictureBox1; public System.Windows.Forms.Label keteranganLabel; private System.Windows.Forms.PictureBox pictureBox2; private System.Windows.Forms.Label label2; private System.Windows.Forms.PictureBox pictureBox4; private System.Windows.Forms.Label label5; private System.Windows.Forms.PictureBox pictureBox3; private System.Windows.Forms.Label label3; private System.Windows.Forms.Button lanjutButton; private System.Windows.Forms.Button keluarButton; private System.Windows.Forms.PictureBox pictureBox5; private System.Windows.Forms.Label label16; private System.Windows.Forms.Label label4; public TextBox noRekText1 { get { return noRekText; } set { noRekText=value; } } public TextBox idJenisTransaksiText1 { get { return idJenisTransaksiText; } set { idJenisTransaksiText=value; } } /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.Container components = null; //private form1 FormPenarikan; public MenuUtamaForm() { // // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call
// } /// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } private void MenuUtamaForm_Load(object sender, System.EventArgs e) { //untuk data Teller conn.Open(); string sql1 = "select * from Teller_bank where nik= '" +nikText.Text+"'"; cmd1 = new OracleCommand(sql1, conn); cmd1.CommandType = CommandType.Text; da1 = new OracleDataAdapter(cmd1); cb1 = new OracleCommandBuilder(da1); ds1 = new DataSet(); da1.Fill(ds1); teller_bank.DataSource = ds1.Tables[0]; DataGridCell dgcteller_bank = teller_bank.CurrentCell; nikText2.Text = teller_bank[dgcteller_bank.RowNumber,0].ToString(); conn.Close(); } private void lanjutButton_Click(object sender, System.EventArgs e) { try { conn.Open(); if (totalSaldoRB.Checked) { string sql = " select id_jenis_transaksi from jenis_transaksi where id_jenis_transaksi = 4"; OracleCommand comd2 = new OracleCommand(sql, conn); OracleDataReader reader4 = comd2.ExecuteReader(); da = new OracleDataAdapter(comd2); cb = new OracleCommandBuilder(da); ds = new DataSet(); da.Fill(ds); Jenis_transaksi.DataSource = ds.Tables[0]; DataGridCell dgcJenis_transaksi = Jenis_transaksi.CurrentCell;
idJenisTransaksiText.Text = Jenis_transaksi[dgcJenis_transaksi.RowNumber,0].ToString(); if (reader4.HasRows) { this.Hide(); //memanggil FormTotalSaldo() FormTotalSaldo form4 = new FormTotalSaldo(); form4.idJenisTransaksiText = idJenisTransaksiText; DialogResult result = form4.ShowDialog(); totalSaldoRB.Checked=false; } } else { string query = "Select * from Nasabah Where No_Rekening = '" +noRekText.Text.Trim()+"'"; OracleCommand cmd = new OracleCommand(query,conn); OracleDataReader reader = cmd.ExecuteReader(); if(reader.HasRows) { if (penarikanRB.Checked) { string sql = " select * from jenis_transaksi where id_jenis_transaksi = 1"; OracleCommand comd2 = new OracleCommand(sql, conn); OracleDataReader reader2 = comd2.ExecuteReader(); da = new OracleDataAdapter(comd2); cb = new OracleCommandBuilder(da); ds = new DataSet(); da.Fill(ds); Jenis_transaksi.DataSource = ds.Tables[0]; DataGridCell dgcJenis_transaksi = Jenis_transaksi.CurrentCell; idJenisTransaksiText.Text = Jenis_transaksi[dgcJenis_transaksi.RowNumber,0].ToString(); if (reader.HasRows) { this.Hide(); //memanggil FormPenarikan() FormPenarikan form1 = new FormPenarikan(); form1.idJenisTransaksiText.Text = idJenisTransaksiText.Text; form1.noRekText = noRekText; form1.nikText = nikText2; //berikut perintah untuk menampilkan FormPenarikan
DialogResult result = form1.ShowDialog(); penarikanRB.Checked=false; } } else if(penyetoranRB.Checked) { string sql = " select id_jenis_transaksi from jenis_transaksi where id_jenis_transaksi = 2"; OracleCommand comd2 = new OracleCommand(sql, conn); OracleDataReader reader2 = comd2.ExecuteReader(); da = new OracleDataAdapter(comd2); cb = new OracleCommandBuilder(da); ds = new DataSet(); da.Fill(ds); Jenis_transaksi.DataSource = ds.Tables[0]; DataGridCell dgcJenis_transaksi = Jenis_transaksi.CurrentCell; idJenisTransaksiText.Text = Jenis_transaksi[dgcJenis_transaksi.RowNumber,0].ToString(); if (reader.HasRows) { this.Hide(); //memanggil FormPenyetoran() FormPenyetoran form2 = new FormPenyetoran(); form2.idJenisTransaksiText = idJenisTransaksiText; form2.noRekText = noRekText; form2.nikText = nikText2; //berikut perintah untuk menampilkan FormPenyetoran DialogResult result = form2.ShowDialog(); penyetoranRB.Checked=false; } } else if (transferSaldoRB.Checked) { string sql = " select id_jenis_transaksi from jenis_transaksi where id_jenis_transaksi = 3"; OracleCommand comd2 = new OracleCommand(sql, conn); OracleDataReader reader3 = comd2.ExecuteReader(); da = new OracleDataAdapter(comd2); cb = new OracleCommandBuilder(da); ds = new DataSet(); da.Fill(ds);
Jenis_transaksi.DataSource = ds.Tables[0]; DataGridCell dgcJenis_transaksi = Jenis_transaksi.CurrentCell; idJenisTransaksiText.Text = Jenis_transaksi[dgcJenis_transaksi.RowNumber,0].ToString(); if (reader.HasRows) { this.Hide(); //memanggil FormTransferSaldo1() FormTransferSaldo1 form3 = new FormTransferSaldo1(); form3.idJenisTransaksiText = idJenisTransaksiText; form3.noRekText = noRekText; form3.nikText = nikText2; //berikut perintah untuk menampilkan FormTransferSaldo1 DialogResult result = form3.ShowDialog(); transferSaldoRB.Checked=false; } } else { MessageBox.Show(" Silakan memilih Jenis Transaksi", "Jenis Transaksi diperlukan", MessageBoxButtons.OK, MessageBoxIcon.Information); } } else { noRekText.Clear(); MessageBox.Show("No Rekening tidak ada, masukan salah"); noRekText.Focus(); } } } catch (OracleException ex) { MessageBox.Show(ex.ToString()); } catch(Exception e1) { MessageBox.Show(e1.ToString()); } finally { conn.Close(); } } private void keluarButton_Click(object sender, System.EventArgs e) { this.Close(); FormUtama form = new FormUtama(); form.Show();
} private void kembaliButton_Click(object sender, System.EventArgs e) { this.Close(); LoginTeller_denganCC form = new LoginTeller_denganCC(); form.Show(); } } }
FormPenarikan.cs using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using Oracle.DataAccess.Client; using Oracle.DataAccess.Types; //using System.Data.OracleClient; using System.Data; namespace _051106 { /// <summary> /// Summary description for FormPenarikan. /// </summary> public class FormPenarikan : System.Windows.Forms.Form { //public class Form2 : Namespace1.Form1 private System.Windows.Forms.PictureBox pictureBox1; private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label2; private System.Windows.Forms.PictureBox pictureBox2; private System.Windows.Forms.Label label9; private System.Windows.Forms.Label label10; private OracleConnection conn = Koneksi.CON; private System.Windows.Forms.DataGrid Nasabah; private OracleCommand cmd, cmd1; private OracleDataAdapter da, da1; private OracleCommandBuilder cb, cb1; private DataSet ds, ds1; public System.Windows.Forms.TextBox noRekText; public System.Windows.Forms.TextBox nikText; public LoginTeller_tanpaCC form; private System.Windows.Forms.Label NominalKredit; private System.Windows.Forms.Label label3; private System.Windows.Forms.TextBox namaText; private System.Windows.Forms.TextBox alamatText; private System.Windows.Forms.Label label4; private System.Windows.Forms.Label label5; private System.Windows.Forms.TextBox noTelpText; private System.Windows.Forms.Label label6; private System.Windows.Forms.TextBox tandaPengenalText; private System.Windows.Forms.Label label7; private System.Windows.Forms.Label label8; private System.Windows.Forms.TextBox kantorCabangText; private System.Windows.Forms.TextBox saldoSebelumText; private System.Windows.Forms.TextBox noRekText2; private System.Windows.Forms.Label label11; private System.Windows.Forms.TextBox noBukuRekText; private System.Windows.Forms.Label label12; private System.Windows.Forms.Label label13; private System.Windows.Forms.TextBox nominalDebetText; public System.Windows.Forms.TextBox idJenisTransaksiText;
private System.Windows.Forms.TextBox nikText2; private System.Windows.Forms.DataGrid teller_bank; public System.Windows.Forms.Label keteranganLabel; private System.Windows.Forms.PictureBox pictureBox3; private System.Windows.Forms.PictureBox pictureBox4; private System.Windows.Forms.Label label14; private System.Windows.Forms.PictureBox pictureBox5; private System.Windows.Forms.Label label15; private System.Windows.Forms.Label label16; private System.Windows.Forms.Button keluarButton; private System.Windows.Forms.Label label18; private System.Windows.Forms.Button okButton; public TextBox nominalDebetText1 { get { return nominalDebetText; } set { nominalDebetText=value; } } /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.Container components = null; public FormPenarikan() { // // Required for Windows Form Designer support // InitializeComponent(); //conn.Open(); // // TODO: Add any constructor code after InitializeComponent call // } /// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { conn.Dispose(); if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); private void FormPenarikan_Load(object sender, System.EventArgs e) { // Untuk data nasabah ybs conn.Open(); string sql = "select * from Nasabah where No_rekening= '" +noRekText.Text+"'"; cmd = new OracleCommand(sql, conn); cmd.CommandType = CommandType.Text; da = new OracleDataAdapter(cmd); cb = new OracleCommandBuilder(da); ds = new DataSet(); da.Fill(ds);
Nasabah.DataSource = ds.Tables[0]; DataGridCell dgcNasabah = Nasabah.CurrentCell; noRekText2.Text = Nasabah[dgcNasabah.RowNumber,0].ToString(); noRekText2.ReadOnly = true; namaText.Text = Nasabah[dgcNasabah.RowNumber,1].ToString(); namaText.ReadOnly = true; alamatText.Text = Nasabah[dgcNasabah.RowNumber,2].ToString(); alamatText.ReadOnly = true; noTelpText.Text = Nasabah[dgcNasabah.RowNumber,3].ToString(); noTelpText.ReadOnly = true; tandaPengenalText.Text = Nasabah[dgcNasabah.RowNumber,4].ToString(); tandaPengenalText.ReadOnly = true; noBukuRekText.Text = Nasabah[dgcNasabah.RowNumber,5].ToString(); noBukuRekText.ReadOnly = true; kantorCabangText.Text = Nasabah[dgcNasabah.RowNumber,6].ToString(); kantorCabangText.ReadOnly = true; saldoSebelumText.Text = Nasabah[dgcNasabah.RowNumber,7].ToString(); saldoSebelumText.ReadOnly = true; conn.Close(); //untuk data Teller conn.Open(); string sql1 = "select * from Teller_bank where nik= '" +nikText.Text+"'"; cmd1 = new OracleCommand(sql1, conn); cmd1.CommandType = CommandType.Text; da1 = new OracleDataAdapter(cmd1); cb1 = new OracleCommandBuilder(da1); ds1 = new DataSet(); da1.Fill(ds1); teller_bank.DataSource = ds1.Tables[0]; DataGridCell dgcteller_bank = teller_bank.CurrentCell; nikText2.Text = teller_bank[dgcteller_bank.RowNumber,0].ToString(); conn.Close(); } private void oracleConnection1_InfoMessage(object sender, System.Data.OracleClient.OracleInfoMessageEventArgs e) { } private void oracleDataAdapter1_RowUpdated(object sender, System.Data.OracleClient.OracleRowUpdatedEventArgs e) { } private void listBox1_SelectedIndexChanged(object sender, System.EventArgs e) { }
private void noRekText_TextChanged(object sender, System.EventArgs e) { } private void idJenisTransaksi_TextChanged(object sender, System.EventArgs e) { } private void nikText_TextChanged(object sender, System.EventArgs e) { } private void label11_Click(object sender, System.EventArgs e) { } private void oracleDataAdapter1_RowUpdated_1(object sender, System.Data.OracleClient.OracleRowUpdatedEventArgs e) { } private void oracleConnection1_InfoMessage_1(object sender, System.Data.OracleClient.OracleInfoMessageEventArgs e) { } private void listBox1_SelectedIndexChanged_1(object sender, System.EventArgs e) { } private void saldoSebelumText_TextChanged(object sender, System.EventArgs e) { } private void okButton_Click(object sender, System.EventArgs e) { string PesanError = "Masukan nominal transaksi >= total saldo. Transaksi ditolak. Silahkan isi nominal transaksi kembali..."; try { conn.Open(); // UNTUK PANGGIL PROSEDUR OracleCommand cmd2 = new OracleCommand(); cmd2.Connection = conn; //Panggil prosedur transaksi_penarikan_tunai cmd2.CommandText = "CC3a_transaksi_penarikan"; cmd2.CommandType = CommandType.StoredProcedure; cmd2.Parameters.Add("p_no_rekening", OracleDbType.Int32).Value = ""+noRekText.Text; cmd2.Parameters.Add("p_nik", OracleDbType.Varchar2).Value = ""+nikText.Text;
cmd2.Parameters.Add("p_nominal_debet", OracleDbType.Int64). Value = ""+nominalDebetText.Text; OracleParameter error = cmd2.Parameters.Add("pesan_error",OracleDbType.Varchar2); error.Direction = ParameterDirection.Output; cmd2.ExecuteReader(); this.Hide(); //memanggil FormPenarikan() FormHasilTransaksi_penarikan form1 = new FormHasilTransaksi_penarikan(); form1.noRekText = noRekText; //berikut perintah untuk menampilkan FormHasilTransaksi DialogResult result = form1.ShowDialog(); } catch (OracleException ex) { MessageBox.Show(PesanError, "Transaksi dibatalkan", MessageBoxButtons.OK, MessageBoxIcon.Information); nominalDebetText.Clear(); } catch { MessageBox.Show(" Silakan memasukkan jumlah nominal penarikan tunai", "Nominal penarikan tunai diperlukan", MessageBoxButtons.OK, MessageBoxIcon.Information); nominalDebetText.Clear(); } finally { conn.Close(); } } private void label14_Click(object sender, System.EventArgs e) { } private void prosedur_total_saldo_TextChanged(object sender, System.EventArgs e) { } private void Teller_bank_Navigate(object sender, System.Windows.Forms.NavigateEventArgs ne) { } private void textBox1_TextChanged(object sender, System.EventArgs e) { } private void keluarButton_Click(object sender, System.EventArgs e)
{ this.Close(); FormUtama form = new FormUtama(); form.Show(); } private void kembaliButton_Click(object sender, System.EventArgs e) { this.Close(); MenuUtamaForm form1 = new MenuUtamaForm(); form1.Show(); } private void label18_Click(object sender, System.EventArgs e) { } } }
FormPenyetoran.cs using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using Oracle.DataAccess.Client; using Oracle.DataAccess.Types; //using System.Data.OracleClient; using System.Data; namespace _051106 { /// <summary> /// Summary description for FormPenyetoran. /// </summary> public class FormPenyetoran : System.Windows.Forms.Form { private System.Windows.Forms.Label label13; private System.Windows.Forms.Label label12; private System.Windows.Forms.TextBox noBukuRekText; private System.Windows.Forms.Label label11; private System.Windows.Forms.TextBox noRekText2; private System.Windows.Forms.TextBox nominalKreditText; private System.Windows.Forms.TextBox kantorCabangText; private System.Windows.Forms.Label label8; private System.Windows.Forms.Label label7; private System.Windows.Forms.TextBox tandaPengenalText; private System.Windows.Forms.Label label6; private System.Windows.Forms.TextBox noTelpText; private System.Windows.Forms.Label label5; private System.Windows.Forms.Label label4; private System.Windows.Forms.TextBox alamatText; private System.Windows.Forms.TextBox namaText; private System.Windows.Forms.Label label3; private System.Windows.Forms.TextBox saldoSebelumText; private System.Windows.Forms.Label NominalKredit; private System.Windows.Forms.DataGrid Nasabah; public System.Windows.Forms.TextBox noRekText; private System.Windows.Forms.Label label10; private System.Windows.Forms.Label label9; private System.Windows.Forms.PictureBox pictureBox2; private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label1; private System.Windows.Forms.PictureBox pictureBox1; private OracleCommand cmd, cmd1; private OracleDataAdapter da, da1;
private OracleCommandBuilder cb, cb1; //private DataColumn dc; private DataSet ds, ds1; private OracleConnection conn = Koneksi.CON; public System.Windows.Forms.TextBox idJenisTransaksiText; private System.Windows.Forms.DataGrid teller_bank; private System.Windows.Forms.TextBox nikText2; public System.Windows.Forms.TextBox nikText; public System.Windows.Forms.Label keteranganLabel; private System.Windows.Forms.Label label15; private System.Windows.Forms.PictureBox pictureBox3; private System.Windows.Forms.PictureBox pictureBox4; private System.Windows.Forms.Label label14; private System.Windows.Forms.PictureBox pictureBox5; private System.Windows.Forms.Button keluarButton; private System.Windows.Forms.Button okButton; private System.Windows.Forms.Label label16; private System.Windows.Forms.Label label18; /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.Container components = null; public FormPenyetoran() { // // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // } /// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } private void label8_Click(object sender, System.EventArgs e) { } private void label7_Click(object sender, System.EventArgs e) { } private void label6_Click(object sender, System.EventArgs e) { } private void label5_Click(object sender, System.EventArgs e) { } private void label4_Click(object sender, System.EventArgs e)
{ } private void label2_Click(object sender, System.EventArgs e) { } private void label1_Click(object sender, System.EventArgs e) { } private void pictureBox1_Click(object sender, System.EventArgs e) { } private void button1_Click(object sender, System.EventArgs e) { } private void label11_Click(object sender, System.EventArgs e) { } private void label10_Click(object sender, System.EventArgs e) { } private void label9_Click(object sender, System.EventArgs e) { } private void pictureBox2_Click(object sender, System.EventArgs e) { } private void FormPenyetoran_Load(object sender, System.EventArgs e) { conn.Open(); string sql = "select * from Nasabah where No_rekening= '" +noRekText.Text+"'"; cmd = new OracleCommand(sql, conn); cmd.CommandType = CommandType.Text; da = new OracleDataAdapter(cmd); cb = new OracleCommandBuilder(da); ds = new DataSet(); da.Fill(ds); Nasabah.DataSource = ds.Tables[0]; DataGridCell dgcNasabah = Nasabah.CurrentCell; noRekText2.Text = Nasabah[dgcNasabah.RowNumber,0].ToString(); noRekText2.ReadOnly = true; namaText.Text = Nasabah[dgcNasabah.RowNumber,1].ToString(); namaText.ReadOnly = true; alamatText.Text = Nasabah[dgcNasabah.RowNumber,2].ToString(); alamatText.ReadOnly = true;
noTelpText.Text = Nasabah[dgcNasabah.RowNumber,3].ToString(); noTelpText.ReadOnly = true; tandaPengenalText.Text = Nasabah[dgcNasabah.RowNumber,4].ToString(); tandaPengenalText.ReadOnly = true; noBukuRekText.Text = Nasabah[dgcNasabah.RowNumber,5].ToString(); noBukuRekText.ReadOnly = true; kantorCabangText.Text = Nasabah[dgcNasabah.RowNumber,6].ToString(); kantorCabangText.ReadOnly = true; saldoSebelumText.Text = Nasabah[dgcNasabah.RowNumber,7].ToString(); saldoSebelumText.ReadOnly = true; conn.Close(); //untuk data Teller conn.Open(); string sql1 = "select * from Teller_bank where nik= '" +nikText.Text+"'"; cmd1 = new OracleCommand(sql1, conn); cmd1.CommandType = CommandType.Text; da1 = new OracleDataAdapter(cmd1); cb1 = new OracleCommandBuilder(da1); ds1 = new DataSet(); da1.Fill(ds1); teller_bank.DataSource = ds1.Tables[0]; DataGridCell dgcteller_bank = teller_bank.CurrentCell; nikText2.Text = teller_bank[dgcteller_bank.RowNumber,0].ToString(); conn.Close(); } private void label10_Click_1(object sender, System.EventArgs e) { } private void batalButton_Click(object sender, System.EventArgs e) { this.Close(); MenuUtamaForm form = new MenuUtamaForm(); form.Show(); } private void okButton_Click(object sender, System.EventArgs e) { try { conn.Open(); // UNTUK PANGGIL PROSEDUR OracleCommand cmd2 = new OracleCommand(); cmd2.Connection = conn; //Panggil prosedur transaksi penyetoran dengan Concurrency Control cmd2.CommandText = "cc3d_transaksi_penyetoran"; cmd2.CommandType = CommandType.StoredProcedure; cmd2.Parameters.Add("p_no_rekening", OracleDbType.Int32).Value = ""+noRekText.Text;
cmd2.Parameters.Add("p_nik", OracleDbType.Varchar2).Value = ""+nikText.Text; cmd2.Parameters.Add("p_nominal_kredit", OracleDbType.Int64). Value = ""+nominalKreditText.Text; //kalau result setnya > 1, pake ExecuteNonQuery() //kalau result setnya = satu, pake ExecuteReader() //Krn result setnya > 1, maka: cmd2.ExecuteNonQuery(); this.Hide(); //memanggil FormPenyetoran() FormHasilTransaksi_penyetoran form1 = new FormHasilTransaksi_penyetoran(); form1.noRekText = noRekText; //berikut perintah untuk menampilkan FormPenyetoran DialogResult result = form1.ShowDialog(); } catch (OracleException ex) { MessageBox.Show(ex.ToString()); } catch { MessageBox.Show(" Silakan memasukkan jumlah nominal penyetoran tunai", "Nominal penyetoran tunai diperlukan", MessageBoxButtons.OK, MessageBoxIcon.Information); nominalKreditText.Clear(); } finally { conn.Close(); } } private void keluarButton_Click(object sender, System.EventArgs e) { this.Close(); FormUtama form = new FormUtama(); form.Show(); } } }
FormTransferSaldo1.cs : using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using Oracle.DataAccess.Client; using Oracle.DataAccess.Types; //using System.Data.OracleClient; using System.Data; namespace _051106 { /// <summary> /// Summary description for FormTransferSaldo1. /// </summary> public class FormTransferSaldo1 : System.Windows.Forms.Form
{ private System.Windows.Forms.Label label13; private System.Windows.Forms.Label label12; private System.Windows.Forms.TextBox noBukuRekText; private System.Windows.Forms.Label label11; private System.Windows.Forms.TextBox noRekText2; private System.Windows.Forms.TextBox kantorCabangText; private System.Windows.Forms.Label label8; private System.Windows.Forms.Label label7; private System.Windows.Forms.TextBox tandaPengenalText; private System.Windows.Forms.Label label6; private System.Windows.Forms.TextBox noTelpText; private System.Windows.Forms.Label label5; private System.Windows.Forms.Label label4; private System.Windows.Forms.TextBox alamatText; private System.Windows.Forms.TextBox namaText; private System.Windows.Forms.Label label3; private System.Windows.Forms.TextBox saldoSebelumText; private System.Windows.Forms.DataGrid Nasabah; public System.Windows.Forms.TextBox noRekText; private System.Windows.Forms.Label label10; private System.Windows.Forms.Label label9; private System.Windows.Forms.PictureBox pictureBox2; private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label1; private System.Windows.Forms.PictureBox pictureBox1; private System.Windows.Forms.Label label14; public System.Windows.Forms.TextBox noRekTujuanText; private OracleCommand cmd; private OracleDataAdapter da; private OracleCommandBuilder cb; //private DataColumn dc; private DataSet ds; private OracleConnection conn = Koneksi.CON; public System.Windows.Forms.TextBox idJenisTransaksiText; public System.Windows.Forms.TextBox nikText; private System.Windows.Forms.Label label15; private System.Windows.Forms.Label label16; private System.Windows.Forms.Label label17; public System.Windows.Forms.Label keteranganLabel; private System.Windows.Forms.TextBox nominalDebetText; private System.Windows.Forms.Label label18; private System.Windows.Forms.PictureBox pictureBox3; private System.Windows.Forms.PictureBox pictureBox4; private System.Windows.Forms.Label label19; private System.Windows.Forms.PictureBox pictureBox5; private System.Windows.Forms.Label label20; private System.Windows.Forms.Label label21; private System.Windows.Forms.Button keluarButton; private System.Windows.Forms.Button okButton; public TextBox noRekTujuanText1 { get { return noRekTujuanText; } set { noRekTujuanText=value; } } /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.Container components = null; public FormTransferSaldo1() {
// // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // } /// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } private void FormTransferSaldo1_Load(object sender, System.EventArgs e) { conn.Open(); //noRekText.Enabled=false; string sql = "select * from Nasabah where No_rekening= '" +noRekText.Text+"'"; cmd = new OracleCommand(sql, conn); cmd.CommandType = CommandType.Text; da = new OracleDataAdapter(cmd); cb = new OracleCommandBuilder(da); ds = new DataSet(); da.Fill(ds); Nasabah.DataSource = ds.Tables[0]; DataGridCell dgcNasabah = Nasabah.CurrentCell; noRekText2.Text = Nasabah[dgcNasabah.RowNumber,0].ToString(); noRekText2.ReadOnly = true; namaText.Text = Nasabah[dgcNasabah.RowNumber,1].ToString(); namaText.ReadOnly = true; alamatText.Text = Nasabah[dgcNasabah.RowNumber,2].ToString(); alamatText.ReadOnly = true; noTelpText.Text = Nasabah[dgcNasabah.RowNumber,3].ToString(); noTelpText.ReadOnly = true; tandaPengenalText.Text = Nasabah[dgcNasabah.RowNumber,4].ToString(); tandaPengenalText.ReadOnly = true; noBukuRekText.Text = Nasabah[dgcNasabah.RowNumber,5].ToString(); noBukuRekText.ReadOnly = true; kantorCabangText.Text = Nasabah[dgcNasabah.RowNumber,6].ToString(); kantorCabangText.ReadOnly = true; saldoSebelumText.Text = Nasabah[dgcNasabah.RowNumber,7].ToString(); saldoSebelumText.ReadOnly = true; conn.Close(); } private void okButton_Click(object sender, System.EventArgs e) {
string PesanError = "Masukan nominal transaksi >= total saldo. Transaksi ditolak. Silahkan isi nominal transaksi kembali..."; try { conn.Open(); if (noRekTujuanText1.Text == noRekText.Text) { noRekTujuanText1.Clear(); MessageBox.Show("No Rekening tujuan harus berbeda dengan No Rekening nasabah"); noRekTujuanText1.Focus(); } string query = "Select * from Nasabah Where No_Rekening = '" +noRekTujuanText.Text.Trim()+"'"; OracleCommand comd = new OracleCommand(query,conn); OracleDataReader reader = comd.ExecuteReader(); if(reader.HasRows) { // UNTUK PANGGIL PROSEDUR OracleCommand cmd2 = new OracleCommand(); cmd2.Connection = conn; //Panggil prosedur transaksi transfer saldo dengan concurrency control cmd2.CommandText = "CC3b_transfer_saldo"; cmd2.CommandType = CommandType.StoredProcedure; cmd2.Parameters.Add("p_no_rekening", OracleDbType.Int32).Value = ""+noRekText.Text; cmd2.Parameters.Add("p_nik", OracleDbType.Varchar2).Value = ""+nikText.Text; cmd2.Parameters.Add("p_nominal_debet", OracleDbType.Int64). Value = ""+nominalDebetText.Text; cmd2.Parameters. Add("p_no_rekening_tujuan", OracleDbType.Int32). Value = ""+noRekTujuanText.Text; OracleParameter error = cmd2.Parameters.Add("pesan_error",OracleDbType.Varchar2); error.Direction = ParameterDirection.Output; //kalau result setnya > 1, pake ExecuteNonQuery() //kalau result setnya = satu, pake ExecuteReader() //Krn result setnya > 1, maka: cmd2.ExecuteNonQuery(); this.Hide(); //memanggil FormHasilTransaksi_trans_sal FormHasilTransaksi_trans_sal form1 = new FormHasilTransaksi_trans_sal(); form1.noRekText = noRekText; form1.noRekTujuanText = noRekTujuanText; //berikut perintah untuk menampilkan FormPenarikan DialogResult result = form1.ShowDialog(); }
else { noRekTujuanText1.Clear(); MessageBox.Show("No Rekening tidak ada, masukan salah"); noRekTujuanText1.Focus(); } } catch (OracleException ex) { MessageBox.Show(PesanError, "Transaksi dibatalkan", MessageBoxButtons.OK, MessageBoxIcon.Information); nominalDebetText.Clear(); } catch { MessageBox.Show(" Silakan memasukkan jumlah nominal penyetoran tunai", "Nominal penyetoran tunai diperlukan", MessageBoxButtons.OK, MessageBoxIcon.Information); nominalDebetText.Clear(); } finally { conn.Close(); } } private void keluarButton_Click(object sender, System.EventArgs e) { this.Close(); FormUtama form = new FormUtama(); form.Show(); } } }
FormTotalSaldo.cs : using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using Oracle.DataAccess.Client; using Oracle.DataAccess.Types; //using System.Data.OracleClient; using System.Data; namespace _051106 { /// <summary> /// Summary description for FormTotalSaldo. /// </summary> public class FormTotalSaldo : System.Windows.Forms.Form { private System.Windows.Forms.PictureBox pictureBox2; private System.Windows.Forms.PictureBox pictureBox1; private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label2; public System.Windows.Forms.TextBox idJenisTransaksiText; public System.Windows.Forms.TextBox nikText; public System.Windows.Forms.TextBox textBox1; public System.Windows.Forms.Label keteranganLabel; private OracleConnection conn = Koneksi.CON; public System.Windows.Forms.TextBox p_jum_tot_saldo;
private System.Windows.Forms.DataGrid totalSaldo; private System.Windows.Forms.Label label18; private System.Windows.Forms.PictureBox pictureBox3; private System.Windows.Forms.PictureBox pictureBox4; private System.Windows.Forms.Label label19; private System.Windows.Forms.PictureBox pictureBox5; private System.Windows.Forms.Label label20; private System.Windows.Forms.Label label21; private System.Windows.Forms.Button keluarButton; private System.Windows.Forms.Button okButton; //public System.Windows.Forms.TextBox nilaiSum; /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.Container components = null; public TextBox p_jum_tot_saldo1 { get { return p_jum_tot_saldo; } set { p_jum_tot_saldo=value; } } public FormTotalSaldo() { // // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // } /// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } private void batalButton_Click(object sender, System.EventArgs e) { this.Close(); MenuUtamaForm form = new MenuUtamaForm(); form.Show(); } private void okButton_Click(object sender, System.EventArgs e) { try { conn.Open(); // UNTUK PANGGIL PROSEDUR OracleCommand cmd2 = new OracleCommand();
cmd2.Connection = conn; //Panggil prosedur transaksi jumlah total saldo dengan concurrency control cmd2.CommandText = "CC3b_jum_tot_sal2"; cmd2.CommandType = CommandType.StoredProcedure; OracleParameter sumParm = cmd2.Parameters.Add("nilai_sum",OracleDbType.Int64); sumParm.Direction = ParameterDirection.Output; //conn.Open(); OracleDataReader sumReader = cmd2.ExecuteReader(); this.Hide(); //memanggil FormHasilTransaksi_tot_sal() FormHasilTransaksi_tot_sal form1 = new FormHasilTransaksi_tot_sal(); form1.setTotSaldo(cmd2.Parameters["nilai_sum"].Value.ToString()); //berikut perintah untuk menampilkan FormHasilTransaksi_tot_sal form1.Show(); form1.p_jum_tot_saldo.ReadOnly = true; //form1.nilaiSum= nilaiSum; } catch (OracleException ex) { MessageBox.Show(ex.ToString()); } catch (Exception e1) { MessageBox.Show(e1.ToString()); } finally { conn.Close(); } } private void FormTotalSaldo_Load(object sender, System.EventArgs e) { } private void keluarButton_Click(object sender, System.EventArgs e) { this.Close(); FormUtama form = new FormUtama(); form.Show(); } private void label20_Click(object sender, System.EventArgs e) { } } }