最近經常碰到類似的sqlite文件損壞的問題,由於使用的是非WAL模式,而且是PRAGMA journal_mode = DELETE。對於這種臨時的備份文件如何影響的,這裏摘一篇作爲資料收集。
摘自:http://www.it165.net/database/html/201310/4691.html
相信很多使用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"
;
04.
if
(File.Exists(path))
//判斷檔案是否存在。是
05.
{
06.
File.Delete(path);
07.
}
08.
09.
SQLiteConnection.CreateFile(path);
//建立SQLite數據庫檔案
10.
11.
using
(SQLiteConnection
conn =
new
SQLiteConnection(
"Data
Source="
+
path +
";Version=3;"
))
//建立聯機
12.
{
13.
14.
using
(SQLiteCommand
comm = conn.CreateCommand())
15.
{
16.
conn.Open();
//開啓數據庫
17.
18.
comm.CommandText
=
"PRAGMA
journal_mode=Off;"
;
//journal
mode 設定爲 OFF(關閉journal模式)
19.
comm.ExecuteNonQuery();
20.
//---下面便只能以journal_mode=Off方式,進行操作-----
21.
22.
//---做一些操作-------------------------------------
23.
comm.CommandText
=
"CREATE
TABLE text_table(id int, value text);"
;
//建立'text_table'數據表
24.
comm.ExecuteNonQuery();
25.
26.
for
(
int
i
= 0; i < 10; ++i)
27.
{
28.
//新增一筆(列)數據到數據表
29.
comm.CommandText
=
"Insert
INTO text_table (id, value) VALUES (0, 'Hello World')"
;
30.
comm.ExecuteNonQuery();
31.
}
32.
//---------------------------------------------------
33.
}
34.
}