sqlite异常掉电相关问题(2)

相信很多使用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. }
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中使用SQLite数据库时,可以通过异常捕获来处理可能出现的错误情况。SQLite库提供了一些异常类和函数,可以帮助我们捕获和处理异常。 在C++中,可以使用try-catch语句块来捕获异常。当某个操作可能引发异常时,我们可以将其放在try块中,然后使用catch块来捕获并处理异常。 以下是一个简单的示例代码,演示了如何在C++中使用SQLite库进行异常捕获: ```cpp #include <iostream> #include <sqlite3.h> int main() { sqlite3* db; int rc; // 打开数据库 rc = sqlite3_open("example.db", &db); if (rc) { // 异常处理:打开数据库失败 std::cerr << "无法打开数据库: " << sqlite3_errmsg(db) << std::endl; sqlite3_close(db); return 1; } // 执行SQL语句 rc = sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS users (id INT, name TEXT);", 0, 0, 0); if (rc != SQLITE_OK) { // 异常处理:执行SQL语句失败 std::cerr << "执行SQL语句失败: " << sqlite3_errmsg(db) << std::endl; sqlite3_close(db); return 1; } // 关闭数据库 rc = sqlite3_close(db); if (rc != SQLITE_OK) { // 异常处理:关闭数据库失败 std::cerr << "关闭数据库失败: " << sqlite3_errmsg(db) << std::endl; return 1; } return 0; } ``` 在上述代码中,我们使用了sqlite3_open、sqlite3_exec和sqlite3_close等函数来打开、执行SQL语句和关闭数据库。如果其中任何一个操作失败,就会抛出异常。我们通过检查返回值来判断是否发生异常,并在catch块中处理异常情况。 请注意,上述代码只是一个简单的示例,实际使用中可能需要更复杂的异常处理逻辑,以满足具体的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值