Bagaimana menjaga informasi status COM+ di Delphi
Liu Xiaoming (cipherliu)
Masalahnya dimulai seperti ini: Saya perlu menulis COM+ untuk terhubung ke database yang berbeda. Beberapa teman mungkin mengatakan bahwa COM+ harus dibuat untuk setiap database, tetapi hal ini tidak dapat dilakukan di sistem saya. Kami sedang membuat sistem bantuan pendidikan, dan penggunanya adalah sekolah (termasuk guru, siswa, dan orang tua di sekolah tersebut tentunya). Kami membangun database untuk setiap sekolah. Struktur databasenya sama. Tentu saja, kami juga memiliki database manajemen untuk mengoordinasikan hubungan antar database. Setiap kali pengguna sekolah ditambahkan, kami mengaktifkan database baru untuk digunakan pelanggan. Dengan kata lain, jumlah database kami terus bertambah, dan kami hanya memiliki satu klien. Kami tidak akan mengembangkan database yang berbeda untuk setiap sekolah di sisi klien, kami hanya memiliki satu set COM+, daripada mengembangkan satu set untuk setiap database. Jadi saya harus membiarkannya terhubung ke database yang berbeda berdasarkan identitas pengguna di COM+.
Jelasnya, COM+ ini harus menyediakan metode yang memungkinkan pemanggilnya (yang dapat berupa aplikasi klien atau middleware lainnya) memilih database yang akan dihubungkan. Dalam praktiknya, kami menanyakan database di perpustakaan manajemen berdasarkan ID penggunanya nama database, lalu sambungkan ke database pengguna. Di sini, untuk menyederhanakan masalah, kami mengira pemanggil sudah mengetahui nama database, dan langsung meminta untuk memanggil database ini.
Tambahkan anggota pribadi DBName:string ke kelas COM+ untuk menyimpan nama database yang akan dihubungkan. Kami juga harus menyediakan metode seperti itu untuk menetapkan nilainya
Prosedur TmtsDBConn.ConnectTo(sDBName:string);
mulai
mencoba
Nama DB:= Nama sDB;
Set Lengkap;
Kecuali
Setel Batalkan;
akhir;
akhir;
Kemudian letakkan kontrol ADOConnection, ADODataSet, dan DataSetProvider di dalamnya, masing-masing diberi nama adoc, adods, dan dsp. Atur hubungan koneksi di antara mereka, atur string koneksi adoc ke database koneksi "DB1", yang merupakan nilai default, dan kemudian di acara BeforeConnect adoc:
adoc.ConnectionString:=ConnectStringA+'Katalog Awal='+NamaDB+';'+ConnectStringC;
ConnectStringA dan ConnectStringC di sini adalah konstanta string yang telah ditentukan sebelumnya untuk membangun string koneksi secara dinamis, sebagai berikut:
konstanta
ConnectStringA='Provider=SQLOLEDB.1;PassWord=2003;Info Keamanan Tetap=Benar;ID Pengguna=sa;';
ConnectStringB='Katalog Awal=DB1;';
ConnectStringC='Sumber Data=server3;Gunakan Prosedur untuk Persiapan=1;Terjemahan Otomatis=Benar;Ukuran Paket=4096;ID Stasiun Kerja=LXM;Gunakan Enkripsi untuk Data=Salah;Tag dengan susunan kolom bila memungkinkan=Salah';
Kompilasi dan instal COM+ ini. Kemudian tulis program klien untuk memanggilnya.
Letakkan DCOMConnection di program klien, sambungkan ke sana dan tulis server COM+, masukkan ClientDataSet, atur properti RemoteServer dan Penyedianya, lalu tulis pernyataan SQL di CommandText-nya. Kemudian, masukkan kontrol DataSource dan kontrol DBGrid untuk membuat koneksi di antara keduanya. Terakhir letakkan tombol dan di acara Kliknya:
Dcomconnection1.Connected:=benar;
Dcomconnection1.AppServer.connect('DB2');
ClientDataset1.Aktif:=true;
Dcomconnection1.Connected:=salah;
Kode ini untuk menguji apakah data di database DB2 dapat diakses. Namun hasilnya ketika mengklik tombol tersebut, selalu dilaporkan kesalahan. Apa alasannya?
Kembali ke proyek COM+, debug, setel breakpoint di ConnectTo dan adocBeforeConnect, dan temukan bahwa program dijalankan sesuai
Nama DB:= Nama sDB;
Saat dijalankan, nilai DBName memang sudah disetel ke "DB2", tetapi saat dijalankan
adoc.ConnectionString:=ConnectStringA+'Katalog Awal='+NamaDB+';'+ConnectStringC;
, DBName menjadi string kosong lagi, sehingga terjadi kesalahan.
Mengapa nilai DBName hilang? Ternyata metode SetComplete dipanggil di ConnectTo. Metode SetComplete menganggap bahwa COM+ telah menyelesaikan tugas dan akan melepaskan objek COM+. Oleh karena itu, saat menyambung ke database, COM+ baru dibuat, dan tentu saja Nama DB-nya batal.
Saya menemukan alasannya, mengubah SetComplete menjadi EnableCommit yang dikompilasi, dan kemudian menjalankan klien. Akhirnya, berhasil dijalankan dan mengambil data dalam database DB2.
Namun, di program klien, saya memasukkan ClientDataSet lain. Setelah membuka ClientDataSet1, saya membuka ClientDataSet2 dan ingin terus mengakses data di DB2, tetapi kesalahan lain dilaporkan. Ubah programnya menjadi
Dcomconnection1.AppServer.connect('DB2');
ClientDataset1.Aktif:=true;
ClientDataset1.Aktif:=salah;
ClientDataset1.Aktif:=true;
Sekalipun hanya satu ClientDataSet yang digunakan, error tetap akan terjadi saat dibuka kembali setelah ditutup.
Tetapi jika klien menulis
Dcomconnection1.AppServer.connect('DB2');
ClientDataset1.Aktif:=true;
Dcomconnection1.AppServer.connect('DB2');
ClientDataset2.Aktif:=true;
Dapat dijalankan dengan sukses. Tapi ini nampaknya sangat jelek. Mengapa COM+ melepaskan dirinya sendiri setelah terhubung ke database?
Ternyata TmtsDataModule memiliki atribut AutoComplete, dan nilai defaultnya adalah true, jadi setelah terhubung ke database, tetap akan rilis sendiri.
Setelah mengatur AutoComplete ke false, kesalahan masih terjadi. Pelacakan pada event OnActivate COM+ menemukan bahwa ketika diaktifkan, atribut AutoComplete secara otomatis disetel ke true, jadi setelah terhubung ke database untuk pertama kalinya, atribut tersebut akan tetap dirilis. diri.
Di acara OnOnActivate COM+, tulis:
LengkapiOtomatis:=salah;
Tidak ada masalah jika klien terhubung satu kali dan mengakses database beberapa kali.
Namun dalam kasus ini, COM+ tidak akan dirilis secara otomatis. Anda perlu menambahkan metode ke COM+, SetComplete dalam metode ini, lalu memanggil metode ini untuk melepaskan COM+ setelah klien selesai dengan COM+.
Setelah eksplorasi di atas, kami sampai pada kesimpulan berikut: Di COM+, jika Anda ingin mempertahankan informasi status, Anda perlu melakukan beberapa pekerjaan, karena COM+ secara default tidak memiliki kewarganegaraan. Setiap kali dipanggil oleh klien, ia akan menilai apakah harusnya rilis sendiri, kalau gak mau rilis harus turun tangan manual, dan terakhir harus rilis manual.