Menggunakan Beberapa Kumpulan Hasil Aktif (MARS)

Berlaku untuk: SQL Server Azure SQL DatabaseAzure SQL Managed InstanceAzure Synapse Analytics AnalyticsPlatform System (PDW)

Unduh driver OLE DB

SQL Server 2005 (9.x) memperkenalkan dukungan untuk beberapa tataan hasil aktif (MARS) dalam aplikasi yang mengakses Mesin Database. Dalam versi SQL Server sebelumnya, aplikasi database tidak dapat mempertahankan beberapa pernyataan aktif pada koneksi. Saat menggunakan SQL Server tataan hasil default, aplikasi harus memproses atau membatalkan semua tataan hasil dari satu batch sebelum dapat menjalankan batch lain pada koneksi tersebut. SQL Server 2005 (9.x) memperkenalkan atribut koneksi baru yang memungkinkan aplikasi memiliki lebih dari satu permintaan yang tertunda per koneksi, dan khususnya, untuk memiliki lebih dari satu tataan hasil default aktif per koneksi.

MARS menyederhanakan desain aplikasi dengan kemampuan baru berikut:

  • Aplikasi dapat memiliki beberapa tataan hasil default yang terbuka dan dapat menyela pembacaan darinya.

  • Aplikasi dapat menjalankan pernyataan lain (misalnya, INSERT, UPDATE, DELETE, dan panggilan prosedur tersimpan) saat tataan hasil default terbuka.

Aplikasi yang menggunakan MARS akan menemukan panduan berikut yang bermanfaat:

  • Kumpulan hasil default harus digunakan untuk kumpulan hasil berumur pendek atau pendek yang dihasilkan oleh pernyataan SQL tunggal (SELECT, DML dengan OUTPUT, RECEIVE, READ TEXT, dan sebagainya).

  • Kursor server harus digunakan untuk tataan hasil yang lebih lama atau besar yang dihasilkan oleh pernyataan SQL tunggal.

  • Selalu baca hingga akhir hasil untuk permintaan prosedural terlepas dari apakah mereka mengembalikan hasil atau tidak, dan untuk batch yang mengembalikan beberapa hasil.

  • Jika memungkinkan, gunakan panggilan API untuk mengubah properti koneksi dan mengelola transaksi di preferensi pernyataan Transact-SQL.

  • Di MARS, peniruan cakupan sesi dilarang saat batch bersamaan berjalan.

Catatan

Secara default, fungsionalitas MARS tidak diaktifkan. Untuk menggunakan MARS saat menyambungkan ke SQL Server dengan Driver OLE DB untuk SQL Server, Anda harus mengaktifkannya secara khusus dalam string koneksi. Untuk informasi selengkapnya, lihat bagian Driver OLE DB untuk SQL Server, nanti dalam topik ini.

Driver OLE DB untuk SQL Server tidak membatasi jumlah pernyataan aktif pada koneksi.

Aplikasi umum yang tidak perlu memiliki lebih dari satu batch multistatement atau prosedur tersimpan yang dijalankan pada saat yang sama akan mendapat manfaat dari MARS tanpa harus memahami bagaimana MARS diimplementasikan. Namun, aplikasi dengan persyaratan yang lebih kompleks memang perlu mempertimbangkan hal ini.

MARS memungkinkan eksekusi interleaved dari beberapa permintaan dalam satu koneksi. Artinya, memungkinkan batch berjalan, dan dalam eksekusinya, memungkinkan permintaan lain untuk dijalankan. Namun, perhatikan bahwa MARS didefinisikan dalam hal interleaving, bukan dalam hal eksekusi paralel.

Infrastruktur MARS memungkinkan beberapa batch untuk dieksekusi secara bergantian, meskipun eksekusi hanya dapat dialihkan pada titik yang ditentukan dengan baik. Selain itu, sebagian besar pernyataan harus berjalan secara atomik dalam batch. Pernyataan yang mengembalikan baris ke klien, yang terkadang disebut sebagai titik hasil, diizinkan untuk menginterogasi eksekusi sebelum selesai saat baris dikirim ke klien, misalnya:

  • SELECT

  • FETCH

  • TERIMA

Pernyataan lain yang dijalankan sebagai bagian dari prosedur tersimpan atau batch harus berjalan hingga selesai sebelum eksekusi dapat dialihkan ke permintaan MARS lainnya.

Cara yang tepat di mana batch eksekusi interleave dipengaruhi oleh sejumlah faktor, dan sulit untuk memprediksi urutan yang tepat di mana perintah dari beberapa batch yang berisi titik hasil akan dijalankan. Berhati-hatilah untuk menghindari efek samping yang tidak diinginkan karena eksekusi interleaved dari batch kompleks tersebut.

Hindari masalah dengan menggunakan panggilan API daripada pernyataan Transact-SQL untuk mengelola status koneksi (SET, USE) dan transaksi (BEGIN TRAN, COMMIT, ROLLBACK) dengan tidak menyertakan pernyataan ini dalam batch multi-pernyataan yang juga berisi titik hasil, dan dengan membuat serialisasi eksekusi batch tersebut dengan mengonsumsi atau membatalkan semua hasil.

Catatan

Prosedur batch atau tersimpan yang memulai transaksi manual atau implisit ketika MARS diaktifkan harus menyelesaikan transaksi sebelum batch keluar. Jika tidak, SQL Server mengembalikan semua perubahan yang dilakukan oleh transaksi ketika batch selesai. Transaksi semacam itu dikelola oleh SQL Server sebagai transaksi cakupan batch. Ini adalah jenis transaksi baru yang diperkenalkan pada SQL Server 2005 (9.x) untuk memungkinkan prosedur tersimpan yang berkinerja baik yang ada untuk digunakan ketika MARS diaktifkan. Untuk informasi selengkapnya tentang transaksi yang dilingkup batch, lihat Pernyataan Transaksi (Transact-SQL).

Untuk contoh penggunaan MARS dari ADO, lihat Menggunakan ADO dengan Driver OLE DB untuk SQL Server.

OLTP Dalam Memori

OLTP dalam memori mendukung MARS menggunakan kueri dan prosedur tersimpan yang dikompilasi secara asli. MARS memungkinkan permintaan data dari beberapa kueri tanpa perlu sepenuhnya mengambil setiap tataan hasil sebelum mengirim permintaan untuk mengambil baris dari kumpulan hasil baru. Agar berhasil membaca dari beberapa tataan hasil terbuka, Anda harus menggunakan koneksi yang diaktifkan MARS.

MARS dinonaktifkan secara default sehingga Anda harus mengaktifkannya secara eksplisit dengan menambahkannya MultipleActiveResultSets=True ke string koneksi. Contoh berikut menunjukkan cara menyambungkan ke instans SQL Server dan menentukan bahwa MARS diaktifkan:

Data Source=MSSQL; Initial Catalog=AdventureWorks; Integrated Security=SSPI; MultipleActiveResultSets=True  

MARS dengan In-Memory OLTP pada dasarnya sama dengan MARS di sisa mesin SQL. Berikut ini mencantumkan perbedaan saat menggunakan MARS dalam tabel yang dioptimalkan memori dan prosedur tersimpan yang dikompilasi secara asli.

MARS dan tabel yang dioptimalkan memori

Berikut ini adalah perbedaan antara tabel berbasis disk dan memori yang dioptimalkan saat menggunakan koneksi yang diaktifkan MARS:

  • Dua pernyataan dapat memodifikasi data dalam objek target yang sama tetapi jika keduanya mencoba memodifikasi rekaman yang sama, konflik tulis-tulis akan menyebabkan operasi baru gagal. Namun, jika kedua operasi memodifikasi rekaman yang berbeda, operasi akan berhasil.

  • Setiap pernyataan berjalan di bawah isolasi SNAPSHOT sehingga operasi baru tidak dapat melihat perubahan yang dibuat oleh pernyataan yang ada. Bahkan jika pernyataan bersamaan dijalankan di bawah transaksi yang sama, mesin SQL membuat transaksi cakupan batch untuk setiap pernyataan yang terisolasi satu sama lain. Namun, transaksi yang tercakup dalam batch masih terikat bersama sehingga pembatalan satu transaksi yang dicakup batch memengaruhi transaksi lain dalam batch yang sama.

  • Operasi DDL tidak diizinkan dalam transaksi pengguna sehingga operasi tersebut akan segera gagal.

MARS dan prosedur tersimpan yang dikompilasi secara asli

Prosedur tersimpan yang dikompilasi secara asli dapat berjalan di koneksi yang diaktifkan MARS dan dapat menghasilkan eksekusi ke pernyataan lain hanya ketika titik hasil ditemui. Titik hasil memerlukan pernyataan SELECT, yang merupakan satu-satunya pernyataan dalam prosedur tersimpan yang dikompilasi secara asli yang dapat menghasilkan eksekusi ke pernyataan lain. Jika pernyataan SELECT tidak ada dalam prosedur yang tidak akan dihasilkannya, pernyataan tersebut akan berjalan hingga selesai sebelum pernyataan lain dimulai.

Transaksi MARS dan OLTP dalam memori

Perubahan yang dibuat oleh pernyataan dan blok atom yang saling berhubungan diisolasi satu sama lain. Misalnya, jika satu pernyataan atau blok atom membuat beberapa perubahan, dan kemudian menghasilkan eksekusi ke pernyataan lain, pernyataan baru tidak akan melihat perubahan yang dibuat oleh pernyataan pertama. Selain itu, ketika pernyataan pertama melanjutkan eksekusi, pernyataan tersebut tidak akan melihat perubahan apa pun yang dibuat oleh pernyataan lain. Pernyataan hanya akan melihat perubahan yang selesai dan diterapkan sebelum pernyataan dimulai.

Transaksi pengguna baru dapat dimulai dalam transaksi pengguna saat ini menggunakan pernyataan BEGIN TRANSACTION - ini hanya didukung dalam mode interop sehingga BEGIN TRANSACTION hanya dapat dipanggil dari pernyataan T-SQL, dan bukan dari dalam prosedur tersimpan yang dikompilasi secara asli. Anda dapat membuat titik penyimpanan dalam transaksi menggunakan SAVE TRANSACTION atau panggilan API ke transaksi. Simpan(save_point_name) untuk memutar kembali ke titik penyimpanan. Fitur ini juga hanya diaktifkan dari pernyataan T-SQL, dan bukan dari dalam prosedur tersimpan yang dikompilasi secara asli.

MARS dan indeks penyimpan kolom

SQL Server (dimulai dengan 2016) mendukung MARS dengan indeks penyimpan kolom. SQL Server 2014 menggunakan MARS untuk koneksi baca-saja ke tabel dengan indeks penyimpan kolom. Namun, SQL Server 2014 tidak mendukung MARS untuk operasi bahasa manipulasi data bersamaan (DML) pada tabel dengan indeks penyimpan kolom. Ketika ini terjadi, SQL Server akan menghentikan koneksi dan membatalkan transaksi. SQL Server 2012 memiliki indeks penyimpan kolom baca-saja dan MARS tidak berlaku untuk mereka.

Menggunakan ADO dengan Driver OLE DB untuk SQL Server

Driver OLE DB untuk SQL Server mendukung MARS melalui penambahan properti inisialisasi sumber data SSPROP_INIT_MARSCONNECTION, yang diimplementasikan dalam kumpulan properti DBPROPSET_SQLSERVERDBINIT. Selain itu, kata kunci string koneksi baru, MarsConn, seperti yang telah ditambahkan. Ini menerima nilai benar atau salah ; false adalah defaultnya.

Properti sumber data DBPROP_MULTIPLECONNECTIONS default ke VARIANT_TRUE. Ini berarti penyedia akan menghasilkan beberapa koneksi untuk mendukung beberapa perintah bersamaan dan objek rowset. Ketika MARS diaktifkan, Driver OLE DB untuk SQL Server dapat mendukung beberapa objek perintah dan set baris pada satu koneksi, sehingga MULTIPLE_CONNECTIONS diatur ke VARIANT_FALSE secara default.

Untuk informasi selengkapnya tentang penyempurnaan yang dilakukan pada kumpulan properti DBPROPSET_SQLSERVERDBINIT, lihat Properti Inisialisasi dan Otorisasi.

Contoh Driver OLE DB untuk SQL Server

Dalam contoh ini, objek sumber data dibuat menggunakan Driver OLE DB untuk SQL Server, dan MARS diaktifkan menggunakan properti DBPROPSET_SQLSERVERDBINIT yang diatur sebelum objek sesi dibuat.

#include <msoledbsql.h>  
  
IDBInitialize *pIDBInitialize = NULL;  
IDBCreateSession *pIDBCreateSession = NULL;  
IDBProperties *pIDBProperties = NULL;  
  
// Create the data source object.  
hr = CoCreateInstance(CLSID_MSOLEDBSQL, NULL,  
   CLSCTX_INPROC_SERVER,  
   IID_IDBInitialize,   
    (void**)&pIDBInitialize);  
  
hr = pIDBInitialize->QueryInterface(IID_IDBProperties, (void**)&pIDBProperties);  
  
// Set the MARS property.  
DBPROP rgPropMARS;  
  
// The following is necessary since MARS is off by default.  
rgPropMARS.dwPropertyID = SSPROP_INIT_MARSCONNECTION;  
rgPropMARS.dwOptions = DBPROPOPTIONS_REQUIRED;  
rgPropMARS.dwStatus = DBPROPSTATUS_OK;  
rgPropMARS.colid = DB_NULLID;  
V_VT(&(rgPropMARS.vValue)) = VT_BOOL;  
V_BOOL(&(rgPropMARS.vValue)) = VARIANT_TRUE;  
  
// Create the structure containing the properties.  
DBPROPSET PropSet;  
PropSet.rgProperties = &rgPropMARS;  
PropSet.cProperties = 1;  
PropSet.guidPropertySet = DBPROPSET_SQLSERVERDBINIT;  
  
// Get an IDBProperties pointer and set the initialization properties.  
pIDBProperties->SetProperties(1, &PropSet);  
pIDBProperties->Release();  
  
// Initialize the data source object.  
hr = pIDBInitialize->Initialize();  
  
//Create a session object from a data source object.  
IOpenRowset * pIOpenRowset = NULL;  
hr = IDBInitialize->QueryInterface(IID_IDBCreateSession, (void**)&pIDBCreateSession));  
hr = pIDBCreateSession->CreateSession(  
   NULL,             // pUnkOuter  
   IID_IOpenRowset,  // riid  
  &pIOpenRowset ));  // ppSession  
  
// Create a rowset with a firehose mode cursor.  
IRowset *pIRowset = NULL;  
DBPROP rgRowsetProperties[2];  
  
// To get a firehose mode cursor request a   
// forward only read only rowset.  
rgRowsetProperties[0].dwPropertyID = DBPROP_IRowsetLocate;  
rgRowsetProperties[0].dwOptions = DBPROPOPTIONS_REQUIRED;  
rgRowsetProperties[0].dwStatus = DBPROPSTATUS_OK;  
rgRowsetProperties[0].colid = DB_NULLID;  
VariantInit(&(rgRowsetProperties[0].vValue));  
rgRowsetProperties[0].vValue.vt = VARIANT_BOOL;  
rgRowsetProperties[0].vValue.boolVal = VARIANT_FALSE;  
  
rgRowsetProperties[1].dwPropertyID = DBPROP_IRowsetChange;  
rgRowsetProperties[1].dwOptions = DBPROPOPTIONS_REQUIRED;  
rgRowsetProperties[1].dwStatus = DBPROPSTATUS_OK;  
rgRowsetProperties[1].colid = DB_NULLID;  
VariantInit(&(rgRowsetProperties[1].vValue));  
rgRowsetProperties[1].vValue.vt = VARIANT_BOOL;  
rgRowsetProperties[1].vValue.boolVal = VARIANT_FALSE;  
  
DBPROPSET rgRowsetPropSet[1];  
rgRowsetPropSet[0].rgProperties = rgRowsetProperties  
rgRowsetPropSet[0].cProperties = 2  
rgRowsetPropSet[0].guidPropertySet = DBPROPSET_ROWSET;  
  
hr = pIOpenRowset->OpenRowset (NULL,  
   &TableID,  
   NULL,  
   IID_IRowset,  
   1,  
   rgRowsetPropSet  
   (IUnknown**)&pIRowset);  

Lihat juga

Driver OLE DB untuk Fitur SQL Server