注册回调函数处理SQLITE_BUSY错误
来源:互联网 发布:阿里云 广告 编辑:程序博客网 时间:2024/06/05 02:26
原文标题:Register A Callback To Handle SQLITE_BUSY Errors
int sqlite3_busy_handle(sqlite3*, int(*)(void *, int), void *);
这个函数设置了一个回调函数,当试图打开一个在另一个线程或进程中被锁住的表时,该回调函数可能会被调用。 (译注:这里用的是"可能"被调用,后面会有解译)
当遇到数据库被锁时,如果回调函数是NULL,那么SQLITE_BUSY或者SQLITE_IOERR_BLOCKED会立刻返回;如果回调函数不为空时,回调函数可能会被调用并传递给它两个参数。
第一个参数是当你调用sqlite_busy_handle函数时传递给它的一个void*的参数的拷贝;第二个参数是因此这次锁事件,该回调函数被调用的次数。
如果回调函数返回0时,将不再尝试再次访问数据库而返回SQLITE_BUSY或者SQLITE_IOERR_BLOCKED。
如果回调函数返回非0, 将会不断尝试操作数据库。
当发生锁争夺时,回调函数不保证每次一定会被调用。当SQLITE检测到调用回调函数会引发死锁现象时,将会直接返回SQLITE_BUSY或者SQLITE_IOERR_BLOCKED而不是调用回调函数。试想下面的情况,操作A拥有一个可读锁并尝试提升为保留锁,而操作B拥有一个保留锁并尝试提升为独占锁,A无法继续操作,因为B的保留锁阻止创建新的保留锁;而B也无法继续操作因为A的可读锁未释放,保留锁就无法提升为独占锁。如果这时两个操作都调用回调函数,那么将都无法继续处理。因此,在这样的情况下,操作A将会返回SQLITE_BUSY,以释放它拥有的可读锁,从而使得操作B可以继续进行。
默认的回调函数为空。
当sqlite处于一个大的事务中,以至于内存缓冲区无法保留所有修改,此时发生的SQLITE_BUSY错误将被转换成SQLITE_IOERR_BLOCKED错误。sqlite此时已经拥有保留锁,并尝试提升为独占锁后将缓冲页面刷新到数据库文件中从而不影响其它并发的读取操作,如果获取独占锁失败,那么内存缓冲区中的数据将处于一个不一致的状态,此时错误代码从相对良好的SQLITE_BUSY提升到为严重的SQLITE_IOERR_BLOCKED。错误的提升会造成强制的回滚。可从CorruptionFollowingBusyError维基页面上查看这样处理的重要性的相关讨论。(译注:对于缓冲区不够的大的事务,sqlite会将部分修改写入回滚日志中,可参阅数据库文件完整性相关的文章)
一个数据库连接只能有一个回调函数,设置新的回调函数将会覆盖原来的。需要注意,调用sqlite3_busy_timeout()也可能会设置或清除当前的回调函数。
回调函数中不要对数据库连接做任何操作,所做的任何操作,可能带来未定义的结果。
回调函数中一定不要关闭数据库连接,或者关闭引发回调函数的语句对象。
- 注册回调函数处理SQLITE_BUSY错误
- GLUT-注册回调函数
- 回调函数_注册
- Delphi7回调函数错误
- 异常处理回调函数
- 注册SMS接收回调函数实例
- SEH的注册回调函数
- 回调函数与注册函数
- VC学习之注册回调函数
- c++ 注册回调函数研究
- J2V8 -- 注册 Java 回调函数
- PHP 的异常处理、错误的抛出及错误回调函数
- PHP 使用回调函数(set_error_handler)处理异常和错误
- C++回调函数的处理
- [转]C++回调函数的处理
- 自设计消息处理回调函数
- C++回调函数的处理
- 回调函数和中断处理函数
- 接口和抽象类的区别
- 把一个具有5个元素的集合划分成三个子集(允许重复),c实现版本
- 带有两个通用类型的模板
- Web应用的性能优化思路——找到瓶颈(转载自OSCHINA)
- Mysql 5.5.3 bug:Can't get hostname for your address
- 注册回调函数处理SQLITE_BUSY错误
- Dijkstra迪杰斯特拉
- 我常去的编程技术网站
- DateTime格式字符串相关
- xen 添加hypercall
- 深圳户口有什么好处??
- 花N天时间研究QtWebKit 做了一个简单的浏览器 呵呵
- 猫 老鼠 人的编程题
- js出现中文乱码及VS打开js文件乱码的解决方法