When using sqlite with multiple data connections, the error of SQLITE_BUSY is often encountered. This is because when using the current connection to access data, it is necessary to apply for a corresponding level of lock, and some of the locks at each level are mutually exclusive. This error is returned when locking. At this time, as long as you wait for a while, wait for other connected operations to be processed, and after releasing the exclusive lock, you can obtain the lock and perform the operation.
However, sqlite3 does not do default processing for retry after sqlite_busy occurs, but provides a processing mechanism busy handle. There are two APIs to create busy handles.
int sqlite3_busy_handler(sqlite3 *, int (*)(void *, int), void *)
The function can define a callback function, which will be called by sqlite when the database is busy
When the callback function is NULL, clear the busy handle, and return directly without applying for a lock
The second function of the callback function will be passed the number of times the function was called by this busy event
If the callback function returns non-zero, the database will retry the current operation, and if it returns 0, the current operation returns SQLITE_BUSY
int sqlite3_busy_timeout(sqlite3*, int ms);
Define a number of milliseconds, when the number of milliseconds is not reached, sqlite will sleep and retry the current operation
If more than ms milliseconds, still can not apply for the required lock, the current operation returns sqlite_BUSY
When ms<=0, clear the busy handle, and return directly without applying for a lock
As can be seen from the above, a function can control the number of timeouts, and a function can control the timeout period
But for a connection, there can only be one busy handle, so the two functions will affect each other. When one is set, the other will be cleared at the same time, which should be selected according to needs.