相信很多使用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
}