Eksekusi Asinkron (Metode Polling)

Sebelum ODBC 3.8 dan Windows 7 SDK, operasi asinkron hanya diizinkan pada fungsi pernyataan. Untuk informasi selengkapnya, lihat Operasi Pernyataan Eksekusi Secara Asinkron, nanti dalam topik ini.

ODBC 3.8 di Windows 7 SDK memperkenalkan eksekusi asinkron pada operasi terkait koneksi. Untuk informasi selengkapnya, lihat bagian Menjalankan Operasi Koneksi ion Secara Asinkron, nanti dalam topik ini.

Di Windows 7 SDK, untuk pernyataan asinkron atau operasi koneksi, aplikasi menentukan bahwa operasi asinkron selesai menggunakan metode polling. Dimulai di Windows 8 SDK, Anda dapat menentukan bahwa operasi asinkron selesai menggunakan metode pemberitahuan. Untuk informasi selengkapnya, lihat Eksekusi Asinkron (Metode Pemberitahuan).

Secara default, driver menjalankan fungsi ODBC secara sinkron; artinya, aplikasi memanggil fungsi dan driver tidak mengembalikan kontrol ke aplikasi sampai selesai menjalankan fungsi. Namun, beberapa fungsi dapat dijalankan secara asinkron; artinya, aplikasi memanggil fungsi, dan driver, setelah pemrosesan minimal, mengembalikan kontrol ke aplikasi. Aplikasi kemudian dapat memanggil fungsi lain saat fungsi pertama masih dijalankan.

Eksekusi asinkron didukung untuk sebagian besar fungsi yang sebagian besar dijalankan pada sumber data, seperti fungsi untuk membuat koneksi, menyiapkan dan menjalankan pernyataan SQL, mengambil metadata, mengambil data, dan melakukan transaksi. Ini paling berguna ketika tugas yang dijalankan pada sumber data membutuhkan waktu lama, seperti proses masuk atau kueri kompleks terhadap database besar.

Ketika aplikasi menjalankan fungsi dengan pernyataan atau koneksi yang diaktifkan untuk pemrosesan asinkron, driver melakukan pemrosesan dalam jumlah minimal (seperti memeriksa argumen untuk kesalahan), memproses tangan ke sumber data, dan mengembalikan kontrol ke aplikasi dengan kode pengembalian SQL_STILL_EXECUTING. Aplikasi kemudian melakukan tugas lain. Untuk menentukan kapan fungsi asinkron telah selesai, aplikasi melakukan polling driver secara berkala dengan memanggil fungsi dengan argumen yang sama seperti yang awalnya digunakan. Jika fungsi masih dijalankan, fungsi akan mengembalikan SQL_STILL_EXECUTING; jika telah selesai dieksekusi, kode yang akan dikembalikan akan dikembalikan jika dijalankan secara sinkron, seperti SQL_SUCCESS, SQL_ERROR, atau SQL_NEED_DATA.

Apakah fungsi dijalankan secara sinkron atau asinkron adalah driver spesifik. Misalnya, metadata tataan hasil di-cache di driver. Dalam hal ini, dibutuhkan sangat sedikit waktu untuk mengeksekusi SQLDescribeCol dan driver hanya harus menjalankan fungsi daripada eksekusi penundaan buatan. Di sisi lain, jika driver perlu mengambil metadata dari sumber data, itu harus mengembalikan kontrol ke aplikasi saat melakukan ini. Oleh karena itu, aplikasi harus dapat menangani kode pengembalian selain SQL_STILL_EXECUTING ketika pertama kali menjalankan fungsi secara asinkron.

Menjalankan Operasi Pernyataan Secara Asinkron

Fungsi pernyataan berikut beroperasi pada sumber data dan dapat dijalankan secara asinkron:

Eksekusi pernyataan asinkron dikontrol berdasarkan per pernyataan atau per koneksi, tergantung pada sumber data. Artinya, aplikasi menentukan bukan bahwa fungsi tertentu akan dijalankan secara asinkron, tetapi bahwa fungsi apa pun yang dijalankan pada pernyataan tertentu adalah untuk dijalankan secara asinkron. Untuk mengetahui mana yang didukung, aplikasi memanggil SQLGetInfo dengan opsi SQL_ASYNC_MODE. SQL_AM_CONNECTION dikembalikan jika eksekusi asinkron tingkat koneksi (untuk handel pernyataan) didukung; SQL_AM_STATEMENT jika eksekusi asinkron tingkat pernyataan didukung.

Untuk menentukan bahwa fungsi yang dijalankan dengan pernyataan tertentu akan dijalankan secara asinkron, aplikasi memanggil SQLSetStmtAttr dengan atribut SQL_ATTR_ASYNC_ENABLE dan mengaturnya ke SQL_ASYNC_ENABLE_ON. Jika pemrosesan asinkron tingkat koneksi didukung, atribut pernyataan SQL_ATTR_ASYNC_ENABLE bersifat baca-saja dan nilainya sama dengan atribut koneksi tempat pernyataan dialokasikan. Ini khusus driver apakah nilai atribut pernyataan diatur pada waktu alokasi pernyataan atau yang lebih baru. Mencoba mengaturnya akan mengembalikan SQL_ERROR dan SQLSTATE HYC00 (Fitur opsional tidak diimplementasikan).

Untuk menentukan bahwa fungsi yang dijalankan dengan koneksi tertentu akan dijalankan secara asinkron, aplikasi memanggil SQLSet Koneksi Attr dengan atribut SQL_ATTR_ASYNC_ENABLE dan mengaturnya ke SQL_ASYNC_ENABLE_ON. Semua handel pernyataan di masa mendatang yang dialokasikan pada koneksi akan diaktifkan untuk eksekusi asinkron; ini ditentukan driver apakah handel pernyataan yang ada akan diaktifkan oleh tindakan ini. Jika SQL_ATTR_ASYNC_ENABLE diatur ke SQL_ASYNC_ENABLE_OFF, semua pernyataan pada koneksi berada dalam mode sinkron. Kesalahan dikembalikan jika eksekusi asinkron diaktifkan saat ada pernyataan aktif pada koneksi.

Untuk menentukan jumlah maksimum pernyataan bersamaan aktif dalam mode asinkron yang dapat didukung driver pada koneksi tertentu, aplikasi memanggil SQLGetInfo dengan opsi SQL_MAX_ASYNC_CONCURRENT_STATEMENTS.

Kode berikut menunjukkan cara kerja model polling:

SQLHSTMT  hstmt1;  
SQLRETURN rc;  
  
// Specify that the statement is to be executed asynchronously.  
SQLSetStmtAttr(hstmt1, SQL_ATTR_ASYNC_ENABLE, SQL_ASYNC_ENABLE_ON, 0);  
  
// Execute a SELECT statement asynchronously.  
while ((rc=SQLExecDirect(hstmt1,"SELECT * FROM Orders",SQL_NTS))==SQL_STILL_EXECUTING) {  
   // While the statement is still executing, do something else.  
   // Do not use hstmt1, because it is being used asynchronously.  
}  
  
// When the statement has finished executing, retrieve the results.  

Saat fungsi dijalankan secara asinkron, aplikasi dapat memanggil fungsi pada pernyataan lain. Aplikasi juga dapat memanggil fungsi pada koneksi apa pun, kecuali yang terkait dengan pernyataan asinkron. Tetapi aplikasi hanya dapat memanggil fungsi asli dan fungsi berikut (dengan handel pernyataan atau koneksi terkait, pegangan lingkungan), setelah operasi pernyataan mengembalikan SQL_STILL_EXECUTING:

Jika aplikasi memanggil fungsi lain dengan pernyataan asinkron atau dengan koneksi yang terkait dengan pernyataan tersebut, fungsi mengembalikan SQLSTATE HY010 (Kesalahan urutan fungsi), misalnya.

SQLHDBC       hdbc1, hdbc2;  
SQLHSTMT      hstmt1, hstmt2, hstmt3;  
SQLCHAR *     SQLStatement = "SELECT * FROM Orders";  
SQLUINTEGER   InfoValue;  
SQLRETURN     rc;  
  
SQLAllocHandle(SQL_HANDLE_STMT, hdbc1, &hstmt1);  
SQLAllocHandle(SQL_HANDLE_STMT, hdbc1, &hstmt2);  
SQLAllocHandle(SQL_HANDLE_STMT, hdbc2, &hstmt3);  
  
// Specify that hstmt1 is to be executed asynchronously.  
SQLSetStmtAttr(hstmt1, SQL_ATTR_ASYNC_ENABLE, SQL_ASYNC_ENABLE_ON, 0);  
  
// Execute hstmt1 asynchronously.  
while ((rc = SQLExecDirect(hstmt1, SQLStatement, SQL_NTS)) == SQL_STILL_EXECUTING) {  
   // The following calls return HY010 because the previous call to  
   // SQLExecDirect is still executing asynchronously on hstmt1. The  
   // first call uses hstmt1 and the second call uses hdbc1, on which  
   // hstmt1 is allocated.  
   SQLExecDirect(hstmt1, SQLStatement, SQL_NTS);   // Error!  
   SQLGetInfo(hdbc1, SQL_UNION, (SQLPOINTER) &InfoValue, 0, NULL);   // Error!  
  
   // The following calls do not return errors. They use a statement  
   // handle other than hstmt1 or a connection handle other than hdbc1.  
   SQLExecDirect(hstmt2, SQLStatement, SQL_NTS);   // OK  
   SQLTables(hstmt3, NULL, 0, NULL, 0, NULL, 0, NULL, 0);   // OK  
   SQLGetInfo(hdbc2, SQL_UNION, (SQLPOINTER) &InfoValue, 0, NULL);   // OK  
}  

Ketika aplikasi memanggil fungsi untuk menentukan apakah masih dijalankan secara asinkron, aplikasi harus menggunakan handel pernyataan asli. Ini karena eksekusi asinkron dilacak berdasarkan per pernyataan. Aplikasi juga harus menyediakan nilai yang valid untuk argumen lain - argumen asli akan dilakukan - untuk melewati pemeriksaan kesalahan di Driver Manager. Namun, setelah driver memeriksa handel pernyataan dan menentukan bahwa pernyataan menjalankan secara asinkron, ia mengabaikan semua argumen lainnya.

Sementara fungsi menjalankan secara asinkron - yaitu, setelah mengembalikan SQL_STILL_EXECUTING dan sebelum mengembalikan kode yang berbeda - aplikasi dapat membatalkannya dengan memanggil SQLCancel atau SQLCancelHandle dengan handel pernyataan yang sama. Ini tidak dijamin untuk membatalkan eksekusi fungsi. Misalnya, fungsi mungkin telah selesai. Selain itu, kode yang dikembalikan oleh SQLCancel atau SQLCancelHandle hanya menunjukkan apakah upaya untuk membatalkan fungsi berhasil, bukan apakah itu benar-benar membatalkan fungsi. Untuk menentukan apakah fungsi dibatalkan, aplikasi memanggil fungsi lagi. Jika fungsi dibatalkan, fungsi mengembalikan SQL_ERROR dan SQLSTATE HY008 (Operasi dibatalkan). Jika fungsi tidak dibatalkan, fungsi mengembalikan kode lain, seperti SQL_SUCCESS, SQL_STILL_EXECUTING, atau SQL_ERROR dengan SQLSTATE yang berbeda.

Untuk menonaktifkan eksekusi asinkron dari pernyataan tertentu ketika driver mendukung pemrosesan asinkron tingkat pernyataan, aplikasi memanggil SQLSetStmtAttr dengan atribut SQL_ATTR_ASYNC_ENABLE dan mengaturnya ke SQL_ASYNC_ENABLE_OFF. Jika driver mendukung pemrosesan asinkron tingkat koneksi, aplikasi memanggil SQLSet Koneksi Attr untuk mengatur SQL_ATTR_ASYNC_ENABLE ke SQL_ASYNC_ENABLE_OFF, yang menonaktifkan eksekusi asinkron dari semua pernyataan pada koneksi.

Aplikasi harus memproses rekaman diagnostik dalam perulangan berulang dari fungsi asli. Jika SQLGetDiagField atau SQLGetDiagRec dipanggil ketika fungsi asinkron dijalankan, fungsi tersebut akan mengembalikan daftar rekaman diagnostik saat ini. Setiap kali panggilan fungsi asli diulang, panggilan fungsi tersebut menghapus rekaman diagnostik sebelumnya.

Menjalankan Operasi Koneksi ion Secara Asinkron

Sebelum ODBC 3.8, eksekusi asinkron diizinkan untuk operasi terkait pernyataan seperti persiapan, eksekusi, dan pengambilan, serta untuk operasi metadata katalog. Mulai dari ODBC 3.8, eksekusi asinkron juga dimungkinkan untuk operasi terkait koneksi seperti menyambungkan, memutuskan, menerapkan, dan memutar kembali.

Untuk informasi selengkapnya tentang ODBC 3.8, lihat Apa yang Baru di ODBC 3.8.

Menjalankan operasi koneksi secara asinkron berguna dalam skenario berikut:

  • Ketika sejumlah kecil utas mengelola sejumlah besar perangkat dengan tingkat data yang sangat tinggi. Untuk memaksimalkan responsivitas dan skalabilitas, diinginkan agar semua operasi menjadi asinkron.

  • Saat Anda ingin tumpang tindih operasi database melalui beberapa koneksi untuk mengurangi waktu transfer yang berlalu.

  • Panggilan ODBC asinkron yang efisien dan kemampuan untuk membatalkan operasi koneksi memungkinkan aplikasi untuk memungkinkan pengguna membatalkan operasi lambat tanpa harus menunggu batas waktu.

Fungsi berikut, yang beroperasi pada handel koneksi, sekarang dapat dijalankan secara asinkron:

Untuk menentukan apakah driver mendukung operasi asinkron pada fungsi-fungsi ini, aplikasi memanggil SQLGetInfo dengan SQL_ASYNC_DBC_FUNCTIONS. SQL_ASYNC_DBC_CAPABLE dikembalikan jika operasi asinkron didukung. SQL_ASYNC_DBC_NOT_CAPABLE dikembalikan jika operasi asinkron tidak didukung.

Untuk menentukan bahwa fungsi yang dijalankan dengan koneksi tertentu akan dijalankan secara asinkron, aplikasi memanggil SQLSet Koneksi Attr dan mengatur atribut SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE ke SQL_ASYNC_DBC_ENABLE_ON. Mengatur atribut koneksi sebelum membuat koneksi selalu dijalankan secara sinkron. Selain itu, operasi mengatur atribut koneksi SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE dengan SQLSet Koneksi Attr selalu dijalankan secara sinkron.

Aplikasi dapat mengaktifkan operasi asinkron sebelum membuat koneksi. Karena Driver Manager tidak dapat menentukan driver mana yang akan digunakan sebelum membuat koneksi, Driver Manager akan selalu mengembalikan keberhasilan di SQLSet Koneksi Attr. Namun, mungkin gagal tersambung jika driver ODBC tidak mendukung operasi asinkron.

Secara umum, mungkin ada paling banyak satu fungsi eksekusi asinkron yang terkait dengan handel koneksi atau handel pernyataan tertentu. Namun, handel koneksi dapat memiliki lebih dari satu handel pernyataan terkait. Jika tidak ada operasi asinkron yang dijalankan pada handel koneksi, handel pernyataan terkait dapat menjalankan operasi asinkron. Demikian pula, Anda dapat memiliki operasi asinkron pada handel koneksi jika tidak ada operasi asinkron yang sedang berlangsung pada handel pernyataan terkait. Upaya untuk menjalankan operasi asinkron menggunakan handel yang saat ini menjalankan operasi asinkron akan mengembalikan HY010, "Kesalahan urutan fungsi".

Jika operasi koneksi mengembalikan SQL_STILL_EXECUTING, aplikasi hanya dapat memanggil fungsi asli dan fungsi berikut untuk handel koneksi tersebut:

  • SQLCancelHandle (pada handel koneksi)

  • SQLGetDiagField

  • SQLGetDiagRec

  • SQLAllocHandle (mengalokasikan ENV/DBC)

  • SQLAllocHandleStd (mengalokasikan ENV/DBC)

  • SQLGetEnvAttr

  • SQLGet Koneksi Attr

  • SQLDataSources

  • SQLDrivers

  • SQLGetInfo

  • SQLGetFunctions

Aplikasi harus memproses rekaman diagnostik dalam perulangan berulang dari fungsi asli. Jika SQLGetDiagField atau SQLGetDiagRec dipanggil ketika fungsi asinkron dijalankan, fungsi tersebut akan mengembalikan daftar rekaman diagnostik saat ini. Setiap kali panggilan fungsi asli diulang, panggilan fungsi tersebut menghapus rekaman diagnostik sebelumnya.

Jika koneksi sedang dibuka atau ditutup secara asinkron, operasi selesai ketika aplikasi menerima SQL_SUCCESS atau SQL_SUCCESS_WITH_INFO dalam panggilan fungsi asli.

Fungsi baru telah ditambahkan ke ODBC 3.8, SQLCancelHandle. Fungsi ini membatalkan enam fungsi koneksi (SQLBrowse Koneksi, SQL Koneksi, SQLDisconnect, SQLDriver Koneksi, SQLEndTran, dan SQLSet Koneksi Attr). Aplikasi harus memanggil SQLGetFunctions untuk menentukan apakah driver mendukung SQLCancelHandle. Seperti halnya SQLCancel, jika SQLCancelHandle mengembalikan keberhasilan, itu tidak berarti operasi dibatalkan. Aplikasi harus memanggil fungsi asli lagi untuk menentukan apakah operasi dibatalkan. SQLCancelHandle memungkinkan Anda membatalkan operasi asinkron pada handel koneksi atau handel pernyataan. Menggunakan SQLCancelHandle untuk membatalkan operasi pada handel pernyataan sama dengan memanggil SQLCancel.

Tidak perlu mendukung operasi koneksi SQLCancelHandle dan asinkron secara bersamaan. Driver dapat mendukung operasi koneksi asinkron tetapi tidak SQLCancelHandle, atau sebaliknya.

Operasi koneksi asinkron dan SQLCancelHandle juga dapat digunakan oleh aplikasi ODBC 3.x dan ODBC 2.x dengan driver ODBC 3.8 dan Driver Manager ODBC 3.8. Untuk informasi tentang cara mengaktifkan aplikasi lama untuk menggunakan fitur baru di versi ODBC yang lebih baru, lihat Matriks Kompatibilitas.

Pengumpulan Koneksi

Setiap kali pengumpulan koneksi diaktifkan, operasi asinkron hanya didukung minimal untuk membuat koneksi (dengan SQL Koneksi dan SQLDriver Koneksi) dan menutup koneksi dengan SQLDisconnect. Tetapi aplikasi masih dapat menangani nilai pengembalian SQL_STILL_EXECUTING dari SQL Koneksi, SQLDriver Koneksi, dan SQLDisconnect.

Saat pengumpulan koneksi diaktifkan, SQLEndTran dan SQLSet Koneksi Attr didukung untuk operasi asinkron.

Contoh

J. Aktifkan eksekusi asinkron fungsi koneksi

Contoh berikut menunjukkan cara menggunakan SQLSet Koneksi Attr untuk mengaktifkan eksekusi asinkron untuk fungsi terkait koneksi.

BOOL AsyncConnect (SQLHANDLE hdbc)   
{  
   SQLRETURN r;  
   SQLHANDLE hdbc;  
  
   // Enable asynchronous execution of connection functions.  
   // This must be executed synchronously, that is r != SQL_STILL_EXECUTING  
   r = SQLSetConnectAttr(  
         hdbc,   
         SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE,  
         reinterpret_cast<SQLPOINTER> (SQL_ASYNC_DBC_ENABLE_ON),  
         0);  
   if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO)   
   {  
      return FALSE;  
   }  
  
   TCHAR szConnStrIn[256] = _T("DSN=AsyncDemo");  
  
   r = SQLDriverConnect(hdbc, NULL, (SQLTCHAR *) szConnStrIn, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);  
  
   if (r == SQL_ERROR)   
   {  
      // Use SQLGetDiagRec to process the error.  
      // If SQLState is HY114, the driver does not support asynchronous execution.  
      return FALSE;  
   }  
  
   while (r == SQL_STILL_EXECUTING)   
   {  
      // Do something else.  
  
      // Check for completion, with the same set of arguments.  
      r = SQLDriverConnect(hdbc, NULL, (SQLTCHAR *) szConnStrIn, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);  
   }  
  
   if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO)   
   {  
      return FALSE;  
   }  
  
   return TRUE;  
}  
  

B. Operasi penerapan asinkron

Contoh ini menunjukkan operasi penerapan asinkron. Operasi putar kembali juga dapat dilakukan dengan cara ini.

BOOL AsyncCommit ()   
{  
   SQLRETURN r;   
  
   // Assume that SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE is SQL_ASYNC_DBC_ENABLE_ON.  
  
   r = SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_COMMIT);  
   while (r == SQL_STILL_EXECUTING)   
   {  
      // Do something else.  
  
      // Check for completion with the same set of arguments.  
      r = SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_COMMIT);  
   }  
  
   if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO)   
   {  
      return FALSE;  
   }  
   return TRUE;  
}  

Lihat Juga

Menjalankan Pernyataan ODBC