加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

SQLite3 掉电非易失原理

(2015-04-14 14:34:48)
标签:

sqlite3

断电

非易失

掉电

sqlite

相信很多使用SQLite3作为资料库的人都会发现一个现象,那就是当SQLite3有做写入的动作时,SQLite3会自动产生一个名为"资料库名称-journal"的暂存档。这是做什么用的呢?

答案是用来Rollback ,换句话说,就是当资料写入资料库有失败动作时,透过journal档案予以复原到未更动前(原始)资料,来确保资料完整与一致性。如果在每次写入的时间很长或频繁的进行资料库写入情况下,因系统(主机)电力不稳或突然断电时,那么下次重新启动,而journal档案若存在,则在开启SQLite资料库时,若发现有journal档案的存在,便会对资料库做Rollback 动作(还原)。
(详细内容:http://www.sqlite.org/atomiccommit.html)。
但是有时候系统(主机)电力不稳或突然断电会导致journal档案损毁,因而造成SQLite资料库无法开启[问题1]。必须(手动)删除journal档案,SQLite资料库才能再度开启。
  
目前所知的方法有两种:
第一种方法:
在系统开机后第一次开启或每一次使用SQLite资料库时,先检查是否已经存在journal档案了,如果是则透过程式自动去删除该journal档案。
但是这有个问题,因为自动删除该journal档案,导致没有Rollback (还原)作用,无法保障资料完整与一致性。缺点二:有时候会发生程式无法自动删除(如:journal档案严重损毁),而导致上面的问题(无法开启资料库)[问题1]再度发生。
 
第二种方法:
使用"PRAGMA journal_mode = OFF"指令,这个指令能关闭自动产生journal暂存档动作。
但是如此一来当在写入资料库的过程,一旦发生意外状况,将会导致SQLite资料库无法保障资料完整与一致性。缺点二:journal_mode设定为OFF时,无法使用交易模式(Transaction)进行操作。
 
第二种方法的缺点二在如果需要使用交易模式(Transaction)进行操作时,可以透过"PRAGMA journal_mode = DELETE"指令,修改回原本的journal模式(journal_mode),就可以使用交易模式(Transaction)。
 
下面的程式码便是第二种方法的实作
01
//请先引用 using System.Data.SQLite;
02
 
03
const string path = @"C:\testDB.db3";//SQLite资料库档案路径
04
 
05
if (File.Exists(path))//判断档案是否存在。是
06
{
07
    File.Delete(path);
08
}
09
 
10
SQLiteConnection.CreateFile(path);//建立SQLite资料库档案
11
 
12
using (SQLiteConnection conn = new SQLiteConnection("Data Source=" + path + ";Version=3;"))//建立连线
13
{
14
                     
15
    using (SQLiteCommand comm = conn.CreateCommand())
16
    {
17
        conn.Open();//开启资料库
18
 
19
        comm.CommandText = "PRAGMA journal_mode=OFF;";//journal mode 设定为 OFF(关闭journal模式)
20
        comm.ExecuteNonQuery();
21
        //---下面便只会以journal_mode=Off方式,进行操作-----
22
                         
23
        //---做一些操作-------------------------------------
24
        comm.CommandText = "CREATE TABLE text_table(id int, value text);";//建立'text_table'资料表
25
        comm.ExecuteNonQuery();
26
 
27
        for (int i = 0; i < 10; ++i)
28
        {
29
            //新增一笔(列)资料到资料表
30
            comm.CommandText = "Insert INTO text_table (id, value) VALUES (0, 'Hello World')";
31
            comm.ExecuteNonQuery();
32
        }
33
        //---------------------------------------------------
34
    }
35
}
 
若如果在确定操作SQLite资料库时,完全不需要使用交易模式(Transaction)下,则下面的程式码,可以在与资料库连线时便先设定以journal mode = OFF模式,进行连线。不需要像上面的程式码额外执行 "PRAGMA journal_mode=OFF;"此一段指令。更方便!!
view sourceprint?
01
//请先引用 using System.Data.SQLite;
02
 
03
const string path = @"C:\testDB.db3";//SQLite资料库档案路径
04
 
05
if (File.Exists(path))//判断档案是否存在。是
06
{
07
    File.Delete(path);
08
}
09
 
10
SQLiteConnection.CreateFile(path);//建立SQLite资料库档案
11
 
12
using (SQLiteConnection conn = new SQLiteConnection("Data Source=" + path + ";Version=3;journal_mode=OFF;"))//建立以关闭journal模式(journal mode=OFF)下进行连线
13
{
14
                     
15
    using (SQLiteCommand comm = conn.CreateCommand())
16
    {
17
        conn.Open();//开启资料库
18
 
19
        //---下面便只会以journal_mode=Off方式,进行操作-----
20
                         
21
        //---做一些操作-------------------------------------
22
        comm.CommandText = "CREATE TABLE text_table(id int, value text);";//建立'text_table'资料表
23
        comm.ExecuteNonQuery();
24
 
25
        for (int i = 0; i < 10; ++i)
26
        {
27
            //新增一笔(列)资料到资料表
28
            comm.CommandText = "Insert INTO text_table (id, value) VALUES (0, 'Hello World')";
29
            comm.ExecuteNonQuery();
30
        }
31
        //---------------------------------------------------
32
    }
33
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有