Aracılığıyla paylaş


Zaman Uyumsuz Yürütme (Sorgulama Yöntemi)

ODBC 3.8 ve Windows 7 SDK'sı öncesinde, zaman uyumsuz işlemlere yalnızca deyim işlevlerinde izin verilirdi. Daha fazla bilgi için bu konunun devamında yer alan Zaman Uyumsuz Olarak Yürütülen Deyim İşlemleri bölümüne bakın.

Windows 7 SDK'sında ODBC 3.8, bağlantıyla ilgili işlemlerde zaman uyumsuz yürütmeyi kullanıma sunar. Daha fazla bilgi için bu konunun devamında yer alan Zaman Uyumsuz Olarak Bağlantı İşlemlerini Yürütme bölümüne bakın.

Windows 7 SDK'sında, zaman uyumsuz deyim veya bağlantı işlemleri için bir uygulama, yoklama yöntemi kullanılarak zaman uyumsuz işlemin tamamlandığını belirledi. Windows 8 SDK'sında başlayarak, bildirim yöntemini kullanarak zaman uyumsuz bir işlemin tamamlandığını belirleyebilirsiniz. Daha fazla bilgi için bkz. Zaman Uyumsuz Yürütme (Bildirim Yöntemi).

Varsayılan olarak, sürücüler ODBC işlevlerini zaman uyumlu olarak yürütür; başka bir ifadeyle, uygulama bir işlevi çağırır ve sürücü, işlevi yürütmeyi bitirene kadar uygulamaya denetim döndürmez. Ancak bazı işlevler zaman uyumsuz olarak yürütülebilir; başka bir ifadeyle, uygulama işlevi çağırır ve sürücü, en az işlemden sonra denetimi uygulamaya döndürür. Uygulama daha sonra ilk işlev yürütülürken diğer işlevleri çağırabilir.

Zaman uyumsuz yürütme, bağlantı kurma, SQL deyimlerini hazırlama ve yürütme, meta verileri alma, veri getirme ve işleme işlemleri gibi veri kaynağında büyük ölçüde yürütülen işlevlerin çoğu için desteklenir. Bu, en çok veri kaynağında yürütülen görevin oturum açma işlemi veya büyük bir veritabanında karmaşık bir sorgu gibi uzun sürmesi halinde kullanışlıdır.

Uygulama, eşzamanlı olmayan işleme için etkinleştirilmiş bir deyim veya bağlantı içeren bir işlev yürüttüğünde, sürücü çok az miktarda işlem gerçekleştirir (bağımsız değişkenleri hatalara karşı kontrol etme gibi), işlemi veri kaynağına devreder ve SQL_STILL_EXECUTING dönüş koduyla kontrolü uygulamaya geri döndürür. Uygulama daha sonra diğer görevleri gerçekleştirir. Asenkron işlevin ne zaman bittiğini belirlemek için, uygulama işlevi başlangıçta kullanılan bağımsız değişkenlerle çağırarak belirli aralıklarla sürücüye sorgulama yapar. İşlev hala yürütülüyorsa SQL_STILL_EXECUTING döndürür; yürütmeyi tamamladıysa, SQL_SUCCESS, SQL_ERROR veya SQL_NEED_DATA gibi zaman uyumlu bir şekilde yürütürse döndüreceği kodu döndürür.

bir işlevin zaman uyumlu olarak mı yoksa zaman uyumsuz olarak mı yürütülürse, sürücüye özgüdür. Örneğin, sonuç kümesi meta verilerinin sürücüde önbelleğe alınıldığını varsayalım. Bu durumda SQLDescribeCol'un yürütülmesi çok az zaman alır ve sürücü yapay olarak yürütmeyi geciktirmek yerine yalnızca işlevi yürütmelidir. Öte yandan, sürücünün veri kaynağından meta verileri alması gerekiyorsa, bunu yaparken uygulamaya denetim döndürmelidir. Bu nedenle, uygulamanın bir işlevi zaman uyumsuz olarak ilk kez yürüttüğünde SQL_STILL_EXECUTING dışında bir dönüş kodunu işleyebilmesi gerekir.

İfade İşlemlerini Eşzamansız Olarak Yürütme

Aşağıdaki deyim işlevleri bir veri kaynağı üzerinde çalışır ve zaman uyumsuz olarak yürütülebilir:

Asenkron bildirim icrası, veri kaynağına bağlı olarak sorgu bazında veya bağlantı bazında denetlenir. Yani, uygulama belirli bir işlevin zaman uyumsuz olarak yürütülmesini değil, belirli bir deyimde yürütülen herhangi bir işlevin zaman uyumsuz olarak yürütülmesini belirtir. Hangisinin desteklendiği öğrenmek için, bir uygulama SQL_ASYNC_MODE seçeneğiyle SQLGetInfo'yı çağırır. Bağlantı düzeyi zaman uyumsuz yürütme (bir deyim tanıtıcısı için) destekleniyorsa SQL_AM_CONNECTION döndürülür; deyim düzeyinde zaman uyumsuz yürütme destekleniyorsa SQL_AM_STATEMENT döndürülür.

Belirli bir deyimle yürütülen işlevlerin zaman uyumsuz olarak yürütüleceğini belirtmek için uygulama, SQL_ATTR_ASYNC_ENABLE özniteliğiyle SQLSetStmtAttr'ı çağırır ve SQL_ASYNC_ENABLE_ON olarak ayarlar. Bağlantı düzeyinde zaman uyumsuz işleme destekleniyorsa, SQL_ATTR_ASYNC_ENABLE deyimi özniteliği yalnızca okunabilir ve değeri, deyimin tahsis edildiği bağlantının bağlantı özniteliği ile aynıdır. Deyim özniteliğinin değerinin deyim ayırma zamanında mı yoksa daha sonra mı ayarlandığı sürücüye özgüdür. Ayarlamaya çalışıldığında SQL_ERROR ve SQLSTATE HYC00 döndürülür (İsteğe bağlı özellik uygulanmaz).

Belirli bir bağlantıyla yürütülen işlevlerin zaman uyumsuz olarak yürütüleceğini belirtmek için, uygulama SQL_ATTR_ASYNC_ENABLE özniteliğiyle SQLSetConnectAttr'ı çağırır ve SQL_ASYNC_ENABLE_ON olarak ayarlar. Gelecekte bağlantı üzerinde ayrılan tüm işlem tanıtıcıları zaman uyumsuz yürütme için etkinleştirilir; mevcut işlem tanıtıcılarının bu işlemle etkinleştirilip etkinleştirilmeyeceği sürücüye bağlı olarak belirlenir. SQL_ATTR_ASYNC_ENABLE SQL_ASYNC_ENABLE_OFF olarak ayarlanırsa, bağlantıdaki tüm deyimler zaman uyumlu modda olur. Bağlantıda etkin bir ifade bulunduğunda zaman uyumsuz yürütme etkinleştirildiğinde bir hata döndürülür.

Sürücünün, belirli bir bağlantıda zaman uyumsuz modda destekleyebileceği en fazla etkin eş zamanlı deyim sayısını belirlemek için uygulama SQLGetInfo SQL_MAX_ASYNC_CONCURRENT_STATEMENTS seçeneğini çağırır.

Aşağıdaki kod, yoklama modelinin nasıl çalıştığını gösterir:

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.  

Bir işlev zaman uyumsuz olarak yürütülürken, uygulama diğer ifadelerdeki işlevleri çağırabilir. Uygulama, eşzamansız deyimle ilişkili olan dışında herhangi bir bağlantıda işlevleri de çağırabilir. Ancak bir deyim işlemi SQL_STILL_EXECUTING döndürdüğünde uygulama yalnızca özgün işlevi ve aşağıdaki işlevleri çağırabilir (deyim tanıtıcısı veya ilişkili bağlantısı, ortam tanıtıcısı ile):

Uygulama, zaman uyumsuz deyimiyle veya bu deyimle ilişkili bağlantıyla başka bir işlevi çağırırsa, işlev SQLSTATE HY010 (İşlev dizisi hatası) döndürür.

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  
}  

Bir uygulama hâlâ asenkron olarak yürütülüp yürütülmediğini belirlemek için bir işlev çağırdığında, özgün ifade tutucusunu kullanmalıdır. Bunun nedeni, zaman uyumsuz yürütmenin her deyim temelinde izlenmesidir. Sürücü Yöneticisi'nde hata denetiminin geçebilmesi için uygulamanın diğer bağımsız değişkenler için de geçerli değerler (özgün bağımsız değişkenlerin yapacağı gibi) sağlaması gerekir. Ancak, sürücü ifade tanıtıcısını kontrol ettikten ve ifadenin zaman uyumsuz olarak yürütüldüğünü belirledikten sonra diğer tüm bağımsız değişkenleri yoksayar.

Fonksiyon zaman uyumsuz olarak yürütülürken - yani SQL_STILL_EXECUTING döndürdükten sonra ve farklı bir kod döndürmeden önce - uygulama, aynı deyim tanıtıcısıyla SQLCancel veya SQLCancelHandle'ı çağırarak iptal edebilir. Bu, işlev yürütmeyi iptal etmek için garanti değildir. Örneğin, işlevi zaten bitmiş olabilir. Ayrıca, SQLCancel veya SQLCancelHandle tarafından döndürülen kod yalnızca işlevi iptal etme girişiminin başarılı olup olmadığını gösterir, işlevi gerçekten iptal edip etmediğini gösterir. İşlevin iptal edilip edilmediğini belirlemek için uygulama işlevi yeniden çağırır. İşlev iptal edildiyse SQL_ERROR ve SQLSTATE HY008 döndürür (İşlem iptal edildi). İşlev iptal edilmediyse SQL_SUCCESS, SQL_STILL_EXECUTING veya farklı bir SQLSTATE ile SQL_ERROR gibi başka bir kod döndürür.

Sürücü deyim düzeyinde zaman uyumsuz işlemeyi desteklediğinde belirli bir deyimin zaman uyumsuz yürütülmesini devre dışı bırakmak için uygulama, SQL_ATTR_ASYNC_ENABLE özniteliğiyle SQLSetStmtAttr'ı çağırır ve SQL_ASYNC_ENABLE_OFF olarak ayarlar. Sürücü bağlantı düzeyinde zaman uyumsuz işlemeyi destekliyorsa, uygulama SQL_ATTR_ASYNC_ENABLE SQL_ASYNC_ENABLE_OFF olarak ayarlamak için SQLSetConnectAttr'i çağırır ve bu da bağlantıdaki tüm deyimlerin zaman uyumsuz yürütülmesini devre dışı bırakır.

Uygulama, özgün işlevin yinelenen döngüsünde tanılama kayıtlarını işlemelidir. Zaman uyumsuz bir işlev yürütülürken SQLGetDiagField veya SQLGetDiagRec çağrılırsa, geçerli tanılama kayıtlarının listesini döndürür. Özgün işlev çağrısı her yinelendiğinde, önceki tanılama kayıtlarını temizler.

Bağlantı İşlemlerini Zaman Uyumsuz Olarak Yürütme

ODBC 3.8'den önce, ifade ile ilgili işlemler olan hazırlama, yürütme ve getirme işlemlerinin yanı sıra katalog meta veri işlemleri için de zaman uyumsuz yürütmeye izin veriliyordu. ODBC 3.8'den başlayarak, bağlanma, bağlantıyı kesme, işleme ve geri alma gibi bağlantıyla ilgili işlemler için zaman uyumsuz yürütme de mümkündür.

ODBC 3.8 hakkında daha fazla bilgi için bkz. ODBC 3.8'deki Yenilikler.

Bağlantı işlemlerini zaman uyumsuz olarak yürütmek aşağıdaki senaryolarda yararlıdır:

  • Az sayıda iş parçacığı çok yüksek veri hızlarına sahip çok sayıda cihazı yönettiğinde. Yanıt hızını ve ölçeklenebilirliği en üst düzeye çıkarmak için tüm işlemlerin zaman uyumsuz olması tercih edilir.

  • Birden çok bağlantı üzerinden veritabanı işlemlerini örtüştürmek, transfer sürelerini azaltmak istediğinizde.

  • Verimli zaman uyumsuz ODBC çağrıları ve bağlantı işlemlerini iptal etme özelliği, bir uygulamanın kullanıcının zaman aşımlarını beklemek zorunda kalmadan herhangi bir yavaş işlemi iptal etmesine olanak tanır.

Bağlantı tanıtıcıları üzerinde çalışan aşağıdaki işlevler artık zaman uyumsuz olarak yürütülebilir:

Bir sürücünün bu işlevlerde zaman uyumsuz işlemleri destekleyip desteklemediğini belirlemek için, bir uygulama SQL_ASYNC_DBC_FUNCTIONS ile SQLGetInfo çağırır. Zaman uyumsuz işlemler destekleniyorsa SQL_ASYNC_DBC_CAPABLE döndürülür. Zaman uyumsuz işlemler desteklenmiyorsa SQL_ASYNC_DBC_NOT_CAPABLE döndürülür.

Belirli bir bağlantıyla yürütülen işlevlerin zaman uyumsuz olarak yürütüleceğini belirtmek için, uygulama SQLSetConnectAttr'i çağırır ve SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE özniteliğini SQL_ASYNC_DBC_ENABLE_ON olarak ayarlar. Bağlantı kurmadan önce bağlantı özniteliğini ayarlamak her zaman zaman zaman uyumlu olarak yürütülür. Ayrıca , SQLSetConnectAttr ile SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE bağlantı özniteliğini ayaran işlem her zaman zaman zaman uyumlu olarak yürütülür.

Bir uygulama, bağlantı oluşturmadan önce zaman uyumsuz işlemi etkinleştirebilir. Sürücü Yöneticisi bağlantı kurmadan önce hangi sürücünün kullanılacağını belirleyemediğinden, Sürücü Yöneticisi sqlSetConnectAttr'de her zaman başarı döndürür. Ancak ODBC sürücüsü zaman uyumsuz işlemleri desteklemiyorsa bağlanamayabilir.

Genel olarak, belirli bir bağlantı tutamacı veya deyim tutamacı ile ilişkili en fazla bir adet zamansal uyumsuz işlem gerçekleştiren işlev olabilir. Ancak, bir bağlantı tanıtıcısının birden fazla ilişkili ifade tanıtıcısı olabilir. Bağlantı işlemcisinde yürütülen bir zaman uyumsuz işlem yoksa, ilişkili bir bağlam tanıtıcısı zaman uyumsuz bir işlemi yürütebilir. Benzer şekilde, ilişkili herhangi bir deyim tanıtıcısında devam eden zaman uyumsuz işlem yoksa, bağlantı tanıtıcısında zaman uyumsuz bir işleminiz olabilir. Şu anda zaman uyumsuz bir işlem yürüten bir tanıtıcı kullanarak zaman uyumsuz bir işlem yürütme girişimi HY010, "İşlev dizisi hatası" döndürür.

Bağlantı işlemi SQL_STILL_EXECUTING döndürürse, uygulama yalnızca özgün işlevi ve bu bağlantı tutamacının aşağıdaki işlevlerini çağırabilir:

  • SQLCancelHandle (bağlantı tanıtıcısında)

  • Sqlgetdiagfield

  • Sqlgetdiagrec

  • SQLAllocHandle (ENV/DBC ayırma)

  • SQLAllocHandleStd (ENV/DBC ayırma)

  • SQLGetEnvAttr

  • Sqlgetconnectattr

  • SQLDataSources

  • SQLDrivers

  • Sqlgetınfo

  • SQLGetFunctions

Uygulama, özgün işlevin yinelenen döngüsünde tanılama kayıtlarını işlemelidir. Zaman uyumsuz bir işlev yürütülürken SQLGetDiagField veya SQLGetDiagRec çağrılırsa, geçerli tanılama kayıtlarının listesini döndürür. Özgün işlev çağrısı her yinelendiğinde, önceki tanılama kayıtlarını temizler.

Bir bağlantı zaman uyumsuz olarak açılıyor veya kapatılıyorsa, uygulama özgün işlev çağrısında SQL_SUCCESS veya SQL_SUCCESS_WITH_INFO aldığında işlem tamamlanır.

ODBC 3.8, SQLCancelHandle'a yeni bir işlev eklendi. Bu işlev altı bağlantı işlevini (SQLBrowseConnect, SQLConnect, SQLDisconnect, SQLDriverConnect, SQLEndTran ve SQLSetConnectAttr) iptal eder. Bir uygulama, sürücünün SQLCancelHandle'ı desteklediğini belirlemek için SQLGetFunctions'ı çağırmalıdır. SQLCancel'de olduğu gibi, SQLCancelHandle başarılı döndürürse, bu işlemin iptal edildiği anlamına gelmez. Bir uygulama, işlemin iptal edilip iptal edilmediğini belirlemek için özgün işlevi yeniden çağırmalıdır. SQLCancelHandle , bağlantı tanıtıcılarında veya deyim tanıtıcılarında zaman uyumsuz işlemleri iptal etmenizi sağlar. SqlCancelHandle kullanarak deyim tanıtıcısındaki bir işlemi iptal etmek, SQLCancel'i çağırmakla aynıdır.

Hem SQLCancelHandle hem de zaman uyumsuz bağlantı işlemlerinin aynı anda desteklenmesi gerekmez. Bir sürücü zaman uyumsuz bağlantı işlemlerini destekleyebilir ancak SQLCancelHandle'ı veya tam tersini desteklemez.

Zaman uyumsuz bağlantı işlemleri ve SQLCancelHandle , ODBC 3.8 sürücüsü ve ODBC 3.8 Sürücü Yöneticisi ile ODBC 3.x ve ODBC 2.x uygulamaları tarafından da kullanılabilir. Daha eski bir uygulamanın sonraki ODBC sürümünde yeni özellikleri kullanmasını etkinleştirme hakkında bilgi için bkz . Uyumluluk Matrisi.

Bağlantı Havuzu Oluşturma

Bağlantı havuzu etkinleştirildiğinde, zaman uyumsuz işlemler yalnızca bağlantı kurmak ( SQLConnect ve SQLDriverConnect ile) ve SQLDisconnect ile bir bağlantıyı kapatmak için en az düzeyde desteklenir. Ancak bir uygulamanın SQLConnect, SQLDriverConnect ve SQLDisconnect'ten SQL_STILL_EXECUTING dönüş değerini işleyebilmesi gerekir.

Bağlantı havuzu etkinleştirildiğinde SQLEndTran ve SQLSetConnectAttr zaman uyumsuz işlemler için desteklenir.

Örnekler

A. Bağlantı işlevlerinin zaman uyumsuz yürütülmesini etkinleştirme

Aşağıdaki örnekte, bağlantıyla ilgili işlevlerde zaman uyumsuz yürütmeyi etkinleştirmek için SQLSetConnectAttr'ın nasıl kullanılacağı gösterilmektedir.

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. Zaman uyumsuz taahhüt işlemleri

Bu örnekte zaman uyumsuz taahhüt işlemleri gösterilmektedir. Geri alma işlemleri de bu şekilde yapılabilir.

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;  
}  

Ayrıca Bkz.

ODBC İfadeleri Yürütme