http://www.sqlite.org/c3ref/busy_handler.html留着自己看的。

Register A Callback To Handle SQLITE_BUSY Errors

注册一个回调函数处理SQLITE_BUSY错误

int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
This routine sets a callback function that might be invoked whenever an attempt is made to open a database table that another thread or process has locked.
本函数的目的是设置一个回调函数,如果你试图去打开一个被别的线程和进程锁定的数据库表的时候,这个回调函数会被调用。
 
If the busy callback is NULL, then SQLITE_BUSY or SQLITE_IOERR_BLOCKED is returned immediately upon encountering the lock. If the busy callback is not NULL, then the callback might be invoked with two arguments.
如果回调函数的参数为NULL,那么SQlite系统会在遇到一个锁的时候马上返回SQLITE_BUSY或者SQLITE_IOERR_BLOCKED。如果这个回调函数的参数不为NULL,那么这个回调函数会被调用,它带有2个参数。
 
The first argument to the busy handler is a copy of the void* pointer which is the third argument to sqlite3_busy_handler(). The second argument to the busy handler callback is the number of times that the busy handler has been invoked for this locking event. If the busy callback returns 0, then no additional attempts are made to access the database and SQLITE_BUSY or SQLITE_IOERR_BLOCKED is returned. If the callback returns non-zero, then another attempt is made to open the database for reading and the cycle repeats.
回调函数中的第一个参数是sqlite3_busy_handler()中的第三个参数的一份拷贝,第二个参数是回调函数因为这个锁定事件而被调用的次数。如果回调函数返回0,那么SQlite系统就不会再尝试访问数据库,SQLITE_BUSY或者SQLITE_IOERR_BLOCKED会被马上返回。如果回调函数返回非0,SQlite系统会再试着访问数据库。
 
The presence of a busy handler does not guarantee that it will be invoked when there is lock contention. If SQLite determines that invoking the busy handler could result in a deadlock, it will go ahead and return SQLITE_BUSY or SQLITE_IOERR_BLOCKED instead of invoking the busy handler. Consider a scenario where one process is holding a read lock that it is trying to promote to a reserved lock and a second process is holding a reserved lock that it is trying to promote to an exclusive lock. The first process cannot proceed because it is blocked by the second and the second process cannot proceed because it is blocked by the first. If both processes invoke the busy handlers, neither will make any progress. Therefore, SQLite returns SQLITE_BUSY for the first process, hoping that this will induce the first process to release its read lock and allow the second process to proceed.
 
这个回调函数不能保证在任何遇到锁的情况下都会被调用。如果SQlite系统认为调用回调函数会导致死锁,那么它会直接返回SQLITE_BUSY或者SQLITE_IOERR_BLOCKED。假如,一个进程持有读锁并且想要试着提升为保留锁,另一个线程持有保留锁并且想要提升为排它锁,那么这种情况可能导致死锁,因为第一个线程在等待第二线程释放保留锁,而第二个线程也在等待第一个线程释放读锁。如果他们都调用回调函数的话,他们都不会获得任何进展。因此,SQLite会返回SQLITE_BUSY给第一个线程,它希望第一个线程能释放读锁,这样就能让第二个线程继续运行了。
 
The default busy callback is NULL.
默认的回调函数是NULL。
 
The SQLITE_BUSY error is converted to SQLITE_IOERR_BLOCKED when SQLite is in the middle of a large transaction where all the changes will not fit into the in-memory cache. SQLite will already hold a RESERVED lock on the database file, but it needs to promote this lock to EXCLUSIVE so that it can spill cache pages into the database file without harm to concurrent readers. If it is unable to promote the lock, then the in-memory cache will be left in an inconsistent state and so the error code is promoted from the relatively benign SQLITE_BUSY to the more severe SQLITE_IOERR_BLOCKED. This error code promotion forces an automatic rollback of the changes. See the CorruptionFollowingBusyError wiki page for a discussion of why this is important.
如果在大型事务中,改变不能存入内存缓冲区, SQLITE_BUSY错误码会变成SQLITE_IOERR_BLOCKED。还有一种情况,如果SQLite持有一个保留锁,为了不让一些读的事务出现数据的不一致,它必须将自己的锁提升为EXLUSIVE(排它)锁,这样才能将缓存页中的数据安全的写入数据库中。如果SQLite不能完成这种提升,内存缓冲区中的数据将会出现不一致,这是错误码会从相对温和的SQLITE_BUSY变成更严重的SQLITE_IOERR_BLOCKEDSQLITE_IOERR_BLOCKED会强迫这些改变的自动回滚。可以去CorruptionFollowingBusyErrorWiki页看看为什么这很重要。
 
There can only be a single busy handler defined for each database connection. Setting a new busy handler clears any previously set handler. Note that callingsqlite3_busy_timeout() will also set or clear the busy handler.
对于每一个数据库连接来说,只能注册一个回调函数,注册任何一个新的回调函数都会替换掉以前那个。注意:调用sqlite3_busy_timeout()也会注册或清除回调函数。
 

The busy callback should not take any actions which modify the database connection that invoked the busy handler. Any such actions result in undefined behavior.

A busy handler must not close the database connection or prepared statement that invoked the busy handler.

任何回调函数都不应该做出修改调用自己的数据库连接的行为,任何这种行为都会导致不可预知的情况。

回调函数必须不能关掉调用自己的数据库连接或者释放掉调用自己的准备语句。

Register A Callback To Handle SQLITE_BUSY Errors(译)的更多相关文章

  1. [Angular] Handle HTTP Errors in Angular with HttpErrorResponse interface

    When communicating with some backend API, data travels over the network using the HTTP protocol. As ...

  2. [React] Handle React Suspense Errors with an Error Boundary

    Error Boundaries are the way you handle errors with React, and Suspense embraces this completely. Le ...

  3. [译]Vulkan教程(02)概况

    [译]Vulkan教程(02)概况 这是我翻译(https://vulkan-tutorial.com)上的Vulkan教程的第2篇. This chapter will start off with ...

  4. 【译】深入理解python3.4中Asyncio库与Node.js的异步IO机制

    转载自http://xidui.github.io/2015/10/29/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3python3-4-Asyncio%E5%BA%93% ...

  5. 【译】JavaScript Promise API

    原文地址:JavaScript Promise API 在 JavaScript 中,同步的代码更容易书写和 debug,但是有时候出于性能考虑,我们会写一些异步的代码(代替同步代码).思考这样一个场 ...

  6. callback回调函数【转】

    请给作者点赞--> 原文链接 什么是回调函数? 我们绕点远路来回答这个问题. 编程分为两类:系统编程(system programming)和应用编程(application programmi ...

  7. 【转载】回调函数(callback)是什么?

    一个很形象的例子: 你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货.在这个例子里,你的电话号码就叫回 ...

  8. callback回调函数理解 相当于this指针

    1.callback函数在微软的官方手册中是这样定义callback函数的:“callback函数是由应用程序定义而由操作系统调用的函数”.   凡是由用户设计而却由windows系统调用的函数,统称 ...

  9. Laravel API Errors and Exceptions: How to Return Responses

    Laravel API Errors and Exceptions: How to Return Responses February 13, 2019 API-based projects are ...

随机推荐

  1. Zabbix 报警通知邮件和微信vim /etc/hosts

    1安装 sendmail # yum -y install sendmail echo 'This is test mail'>body.txt mail -s 'Test mail' 3013 ...

  2. Ionic 项目创建

    1. Ionic介绍 Ionci 是一个强大的HTML5 应用程序框架. 可以帮助您使用Web技术,如HTML, CSS和Javascript构建原生体验的移动应用程序. Ionic主要关注外观和体验 ...

  3. Python 中函数和方法

    函数与方法 class Foo(object): def __init__(self): self.name = 'lcg' def func(self): print(self.name) obj ...

  4. jython研究笔记

    jython目前只支持python2,不支持python3. python中使用第三方包的话需要重新设置lib的地址. public void getHtmlByTxt(String path) { ...

  5. Bootstrap-CL:略缩图

    ylbtech-Bootstrap-CL:略缩图 1.返回顶部 1. Bootstrap 缩略图 本章将讲解 Bootstrap 缩略图.大多数站点都需要在网格中布局图像.视频.文本等.Bootstr ...

  6. [转]命令行在IIS添加虚拟目录

    来自:http://www.jb51.net/softjc/29702.htmlMkwebdir -c LocalHost -w "Default Web Site" –v Com ...

  7. py基础4--迭代器、装饰器、软件开发规范

    本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1. 列表生成式,迭代器&生成器 列表生成式 我现在有个需求, ...

  8. 公司培训lesson 1-代码质量

    课堂讲义 代码质量五大原则 编码规范 命名规范.学会合理科学的命名类名.方法名.变量名.命名宗旨:简洁明了,见名只意:了解常用单词缩写 注释.是否写根据所处工作环境的需要而决定.将以源代码写成以“注释 ...

  9. 使用jenkins SVN MSBuil配置.net mvc网站进行持续集成

    通过多次搭建Jenkins持续构建环境,终于对Jenkins有了进一步认识,在此把所学所得和大家分享一下,希望可以帮助大家快速掌握Jenkins的核心思想.看了很多文章,最终决定使用Jenkins.以 ...

  10. halcon控制显示精度(精确到小数点后6位,精度足够了)

    实践应用 set_tposition (WindowHandle3,50, 50) write_string (WindowHandle3, '半径 D1=' +Ra[i]$'#f') set_tpo ...