int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*);
sqlite3_busy_handler(D,X,P) 例程會設定一個回饋函式 X,當嘗試存取與資料庫連線 D 相關聯的資料表時,若其他執行緒或程序已鎖定該資料表,則可能會以參數 P 呼叫此回饋函式。sqlite3_busy_handler() 介面用於實作 sqlite3_busy_timeout() 和 PRAGMA busy_timeout。
如果忙碌回饋函式為 NULL,則在遇到鎖定时會立即返回 SQLITE_BUSY。如果忙碌回饋函式不是 NULL,則可能會以兩個參數呼叫該回饋函式。
忙碌處理程式的第一個參數是 void* 指標的副本,該指標是 sqlite3_busy_handler() 的第三個參數。忙碌處理程式回饋函式的第二個參數是針對同一個鎖定事件先前已呼叫忙碌處理程式的次數。如果忙碌回饋函式返回 0,則不會再次嘗試存取資料庫,並將 SQLITE_BUSY 返回給應用程式。如果回饋函式返回非零值,則會再次嘗試存取資料庫,並重複此循環。
存在忙碌處理程式並不保證在發生鎖定爭用時會呼叫它。如果 SQLite 判斷呼叫忙碌處理程式可能會導致死結,它會直接向應用程式返回 SQLITE_BUSY,而不是呼叫忙碌處理程式。考慮這樣一種情況:一個程序持有讀取鎖定,它正嘗試將其提升為保留鎖定,而另一個程序持有保留鎖定,它正嘗試將其提升為獨佔鎖定。第一個程序無法繼續,因為它被第二個程序阻塞,而第二個程序無法繼續,因為它被第一個程序阻塞。如果兩個程序都呼叫忙碌處理程式,則兩者都無法取得任何進展。因此,SQLite 會為第一個程序返回 SQLITE_BUSY,希望這能促使第一個程序釋放其讀取鎖定並允許第二個程序繼續。
預設的忙碌回饋函式為 NULL。
每個 資料庫連線 只能定義一個忙碌處理程式。設定新的忙碌處理程式會清除先前設定的任何處理程式。請注意,呼叫 sqlite3_busy_timeout() 或評估 PRAGMA busy_timeout=N 將會更改忙碌處理程式,因此會清除先前設定的任何忙碌處理程式。
忙碌回饋函式不應執行任何修改呼叫忙碌處理程式的資料庫連線的動作。換句話說,忙碌處理程式不可重入。任何此類操作都會導致未定義的行為。
忙碌處理程式不得關閉呼叫忙碌處理程式的資料庫連線或 已準備好的陳述式。