SQLite入门与分析(2)

2025-07-14

另外一个不立即创建一个新文件的原因是,一些数据库的参数,比如:编码,页面大小等,只在在数据库创建前设置。默认情况下,页面大小为1024字节,但是你可以选择512-32768字节之间为 2幂数的数字。有些时候,较大的页面能更有效的处理大量的数据。

(2)执行事务(Perform transactions)

all commands are executed within transactions。

默认情况下,事务自动提交,也就是每一个SQL语句都在一个独立的事务下运行。当然也可以通过使用BEGIN..COMMIT手动提交事务。

(3)断开连接(Disconnect from the database) 主要是关闭数据库文件。

1.5.2、执行Prepared Query

前面提到,预处理查询(Prepared Query)是SQLite执行所有SQL命令的方式,包括以下三个过程:

(1)Prepared Query 分析器(parser)、分词器(tokenizer)和代码生成器(code generator)把SQL Statement编译成VDBE字节码,编译器会创建一个statement句柄(sqlite3_stmt),它包括字节码以及其它执行命令和遍历结果集的所有资源。

相应的C API为sqlite3_prepare(),位于prepare.c文件中,如下:

int sqlite3_prepare(

sqlite3 *db, /* Database handle. */

const char *zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */

sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const char **pzTail /* OUT: End of parsed string */ ){

int rc;

rc = sqlite3LockAndPrepare(db,zSql,nBytes,0,ppStmt,pzTail);

assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ return rc; }

(2) Execution

虚拟机执行字节码,执行过程是一个步进(stepwise)的过程,每一步(step)由sqlite3_step()启动,并由VDBE执行一段字节码。由sqlite3_prepare编译字节代码,并由sqlite3_step()启动虚拟机执行。在遍历结果集的过程中,它返回SQLITE_ROW,当到达结果末尾时,返回SQLITE_DONE。

(3) Finalization

VDBE关闭statement,释放资源。相应的C API为sqlite3_finalize()。

通过下图可以更容易理解该过程:

最后以一个具体的例子结束本节,下节讨论事务。

Code ,/Files/hustcat/2008/Learn.rar #include #include #include \

#include

int main(int argc, char **argv) {

int rc, i, ncols; sqlite3 *db;

sqlite3_stmt *stmt; char *sql;

const char *tail;

//打开数据

rc = sqlite3_open(\

if(rc) {

fprintf(stderr, \ sqlite3_close(db); exit(1); }

sql = \ //预处理

rc = sqlite3_prepare(db, sql, (int)strlen(sql), &stmt, &tail);

if(rc != SQLITE_OK) {

fprintf(stderr, \ }

rc = sqlite3_step(stmt);

ncols = sqlite3_column_count(stmt);

while(rc == SQLITE_ROW) {

for(i=0; i < ncols; i++) {

fprintf(stderr, \ }

fprintf(stderr, \

rc = sqlite3_step(stmt); }

//释放statement sqlite3_finalize(stmt); //关闭数据库

sqlite3_close(db);

return 0; }

主要参考:The Definitive Guide to SQLite

(二)设计与概念(续)

写在前面:本节讨论事务,事务是DBMS最核心的技术之一.在计算机科学史上,有三位科学家

因在数据库领域的成就而获ACM奖,而其中之一Jim Gray(曾任职微软)就是因为在事务处理方面的成就而获得这一殊荣,正是因为他,才使得OLTP系统在随后直到今天大行其道.关于事务处理技术,涉及到很多,随便就能写一本书.在这里我只讨论SQLite事务实现的一些原理,SQLite的事务实现与大型通用的DBMS相比,其实现比较简单.这些内容可能比较偏于理论,但却不难,也是理解其它内容的基础.好了,下面开始第二节---事务.

2、事务(Transaction)

2.1、事务的周期(Transaction Lifecycles)

程序与事务之间有两件事值得注意:

(1)哪些对象在事务下运行——这直接与API有关。

(2)事务的生命周期,即什么时候开始,什么时候结束以及它在什么时候开始影响别的连接(这点对于并发性很重要)——这涉及到SQLite的具体实现。

一个连接(connection)可以包含多个(statement),而且每个连接有一个与数据库关联的B-tree和一个pager。Pager在连接中起着很重要的作用,因为它管理事务、锁、内存缓存以及负责崩溃恢复(crash recovery)。当你进行数据库写操作时,记住最重要的一件事:在任何时候,只在一个事务下执行一个连接。这些回答了第一个问题。

一般来说,一个事务的生命和statement差不多,你也可以手动结束它。默认情况下,事务自动提交,当然你也可以通过BEGIN..COMMIT手动提交。接下来就是锁的问题。

2.2、锁的状态(Lock States)

锁对于实现并发访问很重要,而对于大型通用的DBMS,锁的实现也十分复杂,而SQLite相对较简单。通常情况下,它的持续时间和事务一致。一个事务开始,它会先加锁,事务结束,释放锁。但是系统在事务没有结束的情况下崩溃,那么下一个访问数据库的连接会处理这种情况。

在SQLite中有5种不同状态的锁,连接(connection)任何时候都处于其中的一个状态。下图显示了相应的状态以及锁的生命周期。

关于这个图有以下几点值得注意:

(1)一个事务可以在UNLOCKED,RESERVED或EXCLUSIVE三种状态下开始。默认情况下在UNLOCKED时开始。

(2)白色框中的UNLOCKED, PENDING, SHARED和 RESERVED可以在一个数据库的同一时存在。 (3)从灰色的PENDING开始,事情就变得严格起来,意味着事务想得到排斥锁(EXCLUSIVE)(注意与白色框中的区别)。

虽然锁有这么多状态,但是从体质上来说,只有两种情况:读事务和写事务。

2.3、读事务(Read Transactions)

我们先来看看SELECT语句执行时锁的状态变化过程,非常简单:一个连接执行select语句,触发一个事务,从UNLOCKED到SHARED,当事务COMMIT时,又回到UNLOCKED,就这么简单。

考虑下面的例子(为了简单,这里用了伪码): db = open('foods.db') db.exec('BEGIN')

db.exec('SELECT * FROM episodes') db.exec('SELECT * FROM episodes') db.exec('COMMIT') db.close()


SQLite入门与分析(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:五英期中试卷

相关阅读
本类排行
× 游客快捷下载通道(下载后可以自由复制和排版)

下载本文档需要支付 7

支付方式:

开通VIP包月会员 特价:29元/月

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:xuecool-com QQ:370150219