1. Metode keluar
Saya awalnya berpikir bahwa proses akan segera keluar setelah metode Keluar dijalankan, tetapi saya berubah pikiran setelah saya benar-benar membuat contoh untuk mengujinya. Silakan lihat ini
Misalnya, bendera akhirnya diberi nilai 'C'.
==================== =================
var
bendera: tali;
mulai
mencoba
bendera := 'A';
KELUAR;
bendera := 'B';
Akhirnya
bendera := 'C';
akhir;
bendera := 'D';
akhir;
==================== =================
Analisis: Tidak peduli bagaimana klausa try berakhir, klausa akhirnya selalu dieksekusi. (Terima kasih ylmg netizen)
2. Masalah kecil yang dapat membuat seluruh sistem terhenti
Dalam desain sistem basis data, operasi transaksi sering digunakan untuk memastikan integritas data. Namun, desain yang tidak tepat dapat menimbulkan dampak yang relatif besar. Contoh berikut menggambarkan bahwa meskipun integritas data terjamin, sistem mungkin berhenti berfungsi sepenuhnya:
==================== =================
AdoConnection1.BeginTrans;
mencoba
...
if application.MessageBox('Apakah Anda yakin untuk menghapus?', 'Pertanyaan', MB_YESNO+MB_ICONQUESTION)<>IDYa, kalau begitu //(1)
mulai
...
akhir;
Application.MessageBox('Operasi gagal', 'Peringatan', MB_OK);
AdoConnection1.CommitTrans;
kecuali
Application.MessageBox('Operasi gagal', 'Peringatan', MB_OK); //(3)
AdoConnection1.RollbackTrans;
akhir;
==================== =================
Analisis: Masalah pada kode di atas semua disebabkan oleh Application.MessageBox pada (1), (2), dan (3), namun bukan Application.MessageBox itu sendiri yang menyebabkan masalah, melainkan program hang dan membutuhkan pengguna intervensi. , dan kemudian melanjutkan melakukan operasi selanjutnya; jika pengguna meninggalkan komputer saat ini, atau tidak mengonfirmasi pengoperasian kotak dialog ini, dapat dibayangkan bahwa seluruh sistem dalam keadaan menunggu karena transaksi ini belum berakhir. .
Untuk menghindari masalah ini, ada dua prinsip:
(1) Setelah transaksi dimulai, program dapat secara otomatis mengakhiri transaksi tanpa campur tangan pengguna;
(2) Lakukan operasi terpendek dalam transaksi.
3. coba...kecuali...struktur akhir
Berikut adalah contoh untuk menggambarkan struktur try, atau contoh penggunaan operasi transaksi:
Kode yang dimaksud:
==================== =================
mencoba
...
AdoConnection1.BeginTrans;
...
AdoConnection1.CommitTrans;
kecuali
AdoConnection1.RollbackTrans;
akhir;
==================== =================
Analisis: Jika terjadi pengecualian pada kode setelah mencoba AdoConnection1.BeginTrans, maka akan melompat ke AdoConnection1.RollbackTrans untuk dieksekusi. Namun, AdoConnection1 tidak memulai transaksi karena kesalahan, sehingga terjadi kesalahan selama eksekusi AdoConnection1.RollbackTrans.
Kode yang benar : ================ = ==================================
AdoConnection1.BeginTrans;
mencoba
...
...
AdoConnection1.CommitTrans;
kecuali
AdoConnection1.RollbackTrans;
akhir;
==================== =================
Singkatnya, struktur try digunakan untuk melindungi operasi abnormal. Jika terjadi pengecualian antara try...kecuali, operasi antara kecuali...akhir akan dijalankan. Saat merancang perintah try, Anda harus memperhatikan rasionalitas dari arsitektur.
4. Menipu perlindungan transaksi diri sendiri
Saat membuat perangkat lunak aplikasi database, kita sering menghadapi masalah berikut: menilai data asli dan kemudian melakukan modifikasi yang sesuai. Masalah ini tampaknya relatif sederhana, tetapi mengingat ada orang lain di jaringan yang menggunakan sistem yang sama, maka Anda harus mempertimbangkan kemungkinan perubahan yang tidak disengaja. Rekan saya ceroboh. Meskipun dia mempertimbangkan masalah multi-pengguna setelah saya meminta, dia masih menulis kode yang bermasalah:
==================== =================
var
suhu iklan: TAdoDataSet;
baiklah: boolean;
mulai
adsTemp := TAdoDataSet.Create(mandiri);
mencoba
adsTemp.Connection := AdoConnection1;
adsTemp.CommandText := 'pilih fid, fnumber dari tb1 di mana fid=120';
adsTemp.Open;
isOk := adsTemp.FieldByName('fnumber').AsInteger>100;
Akhirnya
iklanTemp.Gratis;
akhir;
jika tidak, okelah
KELUAR;
AdoConnection1.BeginTrans;
mencoba
AdoConnection1.Execute('perbarui tb1 set ffull=ffull + 1 dari tb1 di mana fid=120';
...
...
AdoConnection1.CommitTrans;
kecuali
AdoConnection1.RollbackTrans;
akhir;
akhir;
==================== =================
Analisis: Saya tidak tahu apakah Anda pernah melihat masalahnya. Data dinilai sebelum AdoConnection1.BeginTrans, dan kemudian AdoConnection1.Execute digunakan untuk mengubah data. Jika data dibagikan, maka selama periode setelah penilaian ke sebelumnya AdoConnection1.BeginTrans, tb1 Data mungkin telah berubah, dan perlindungan transaksi ini tidak ada gunanya.
Metode yang benar adalah penilaian dan modifikasinya harus data yang sama. Contoh berikut menunjukkan dua metode (perbedaannya adalah lokasi dimulainya transaksi berbeda):
Kode 1 (setelah menggunakan perlindungan transaksi, data yang sama dinilai dan diubah):
==================== =================
var
suhu iklan: TAdoDataSet;
baiklah: boolean;
mulai
AdoConnection1.BeginTrans;
mencoba
adsTemp := TAdoDataSet.Create(mandiri);
mencoba
adsTemp.Connection := AdoConnection1;
adsTemp.CommandText := 'pilih fid, fnumber, ffull dari tb1 di mana fid=120';
adsTemp.Open;
jika adsTemp.FieldByName('fnumber').AsInteger>100 maka
mulai
adsTemp.Edit;
adsTemp.FieldByName('ffull').AsInteger := adsTemp.FieldByName('ffull').AsInteger + 1;
adsTemp.Post;
akhir;
Akhirnya
iklanTemp.Gratis;
akhir;
AdoConnection1.CommitTrans;
kecuali
AdoConnection1.RollbackTrans;
akhir;
akhir;
==================== =================
Kode 2 (menggunakan capture pengecualian, jika penilaian dan modifikasi data tidak sama, pengecualian akan terjadi selama adsTemp.Post. Ini adalah fitur dari objek ADODataSet):
==================== =================
var
suhu iklan: TAdoDataSet;
baiklah: boolean;
mulai
adsTemp := TAdoDataSet.Create(mandiri);
mencoba
adsTemp.Connection := AdoConnection1;
adsTemp.CommandText := 'pilih fid, fnumber, ffull dari tb1 di mana fid=120';
adsTemp.Open;
jika adsTemp.FieldByName('fnumber').AsInteger>100 maka
mulai
AdoConnection1.BeginTrans;
mencoba
adsTemp.Edit;
adsTemp.FieldByName('ffull').AsInteger := adsTemp.FieldByName('ffull').AsInteger + 1;
adsTemp.Post;
AdoConnection1.CommitTrans;
kecuali
AdoConnection1.RollbackTrans;
akhir;
akhir;
Akhirnya
iklanTemp.Gratis;
akhir;
akhir;