SQLite 3 优化批量数据存储操作---事务transaction机制

news2024/11/29 8:57:42

0、事务操作

事务的目的是为了保证数据的一致性和完整性

事务(Transaction)具有以下四个标准属性,通常根据首字母缩写为 ACID:

  • 原子性(Atomicity):确保工作单位内的所有操作都成功完成,否则,事务会在出现故障时终止,之前的操作也会回滚到以前的状态。
  • 一致性(Consistency):确保数据库在成功提交的事务上正确地改变状态。
  • 隔离性(Isolation):使事务操作相互独立和透明。
  • 持久性(Durability):确保已提交事务的结果或效果在系统发生故障的情况下仍然存在。

开启事务操作相比不开启事务操作的优势

①、性能提升:可以避免频繁地访问磁盘,因为磁盘I/O操作比内存操作慢得多。将数据先写入缓存可以批量处理磁盘写入,减少磁盘I/O次数,从而提高效率。

②、事务管理:缓存机制有助于实现事务的回滚功能。如果事务执行过程中出现错误,可以轻松地从缓存中清除未提交的更改,而不必去磁盘上进行复杂的恢复操作。

③、持久化:当事务被提交时,缓存中的数据会被写入到数据库文件中,这个过程称为“刷盘”。这样做的目的是为了确保数据的持久性,即一旦事务提交,数据更改就成为永久的,即使系统崩溃,数据也不会丢失。

1、事务开始

事务可以是延迟的立即的独占的,默认事务行为是延迟的。

DEFERRED:直到第一次访问数据库时事务才真正开始。

IMMEDIATE:使数据库连接立即开始新的写入,而不等待写入语句。如果另一个写事务已经在另一个数据库连接上处于活动状态, BEGIN IMMEDIATE 可能会失败并返回SQLITE_BUSY

EXCLUSIVE:与 IMMEDIATE 类似,但是更加强制,等待所有读取和写入操作完成。

事务类型在BEGIN命令中指定:

BEGIN [ DEFERRED | IMMEDIATE | EXCLUSIVE ] TRANSACTION;

/**
  * @brief  数据库事务开始
  * @param  db:数据库文件描述符
  * @retval 成功返回0, 失败返回-1
  */
int database_transaction_begin(sqlite3 *db)
{
    char* err_msg = NULL;
    char* beginTransactionCmd = "BEGIN TRANSACTION;";
    int beginRet = sqlite3_exec(db, beginTransactionCmd, NULL, NULL, &err_msg);
    if (beginRet != SQLITE_OK) 
    {
        int sqliteErrCode = sqlite3_errcode(db);
        DBUG_SHOW("Begin transaction errorcode:%d\terror: %s\n", sqliteErrCode, err_msg);
        sqlite3_free(err_msg);
        return -1;
    }
    DBUG_SHOW("Transaction started successfully.\n");
    return 0;
}

2、事务提交

事务的目的是为了保证数据的一致性和完整性,而 COMMIT 命令则是将事务中的修改写入磁盘,以保证数据的持久性。

END TRANSACTION 是 COMMIT 的别名。

/**
  * @brief  数据库事务提交
  * @param  db:数据库文件描述符
  * @retval 成功返回0, 失败返回-1
  */
int database_transaction_commit(sqlite3* db)
{
    char* err_msg = NULL;
    char commitCmd[] = "COMMIT;";
    int commitRet = sqlite3_exec(db, commitCmd, NULL, NULL, &err_msg);
    if (commitRet != SQLITE_OK) 
    {
        int sqliteErrCode = sqlite3_errcode(db);
        DBUG_SHOW("Commit transaction errorcode:%d\terror: %s\n", sqliteErrCode, err_msg);
        sqlite3_free(err_msg);
        return -1;
    }
    DBUG_SHOW("Transaction committed successfully.\n");
    
    return 0;
}

3、事务回滚

事务是一组数据库操作,它们被视为一个单独的工作单元,要么全部成功执行,要么全部回滚。

在一个事务中,可以执行多个SQL语句,如:插入、删除、更新数据操作,但如果在执行过程中出现错误时,可以使用ROLLBACK回滚操作,撤销所有的更改恢复数据库到上一次提交数据操作的状态。

/**
  * @brief  数据库事务回滚
  * @param  db:数据库文件描述符
  * @retval 成功返回0, 失败返回-1
  */
int database_transaction_rollback(sqlite3* db)
{
    char* err_msg = NULL;
    char rollbackCmd[] = "ROLLBACK;";
    int rollbackRet = sqlite3_exec(db, rollbackCmd, NULL, NULL, &err_msg);
    if (rollbackRet != SQLITE_OK) 
    {
        int sqliteErrCode = sqlite3_errcode(db);
        DBUG_SHOW("Rollback transaction errorcode:%d\terror: %s\n", sqliteErrCode, err_msg);
        sqlite3_free(err_msg);
        return -1;
    }
    DBUG_SHOW("Transaction rolled back.\n");
    return 0;
}

4、读写事务

读取事务仅用于读取,写事务允许读取和写入。

读事务由 SELECT 语句启动,写事务由 CREATE、DELETE、DROP、INSERT 或 UPDATE 等语句(统称为“写语句”)启动。

开启了事务操作后,事务的写入并非立即写入到数据库存储文件中,而是被保存在缓存区中,只有进行了事务提交,缓冲区的数据才被写入到事务。

SQLite 支持来自不同数据库连接的多个同时读取事务,可能在不同的线程或进程中,但只支持一个同时写入事务。

/**
  * @brief  写入数据到数据库中
  * @param  db:数据库文件描述符
  * @param  data_cmd:写入数据命令
  * @retval 写入成功返回0,失败-1  
  */
int write_data_to_database(sqlite3* db, char* data_cmd)
{
    //"create table if not exists camera(time_stamp integer primary key, direction text, action text, x integer, y integer, z integer, vx integer, vy integer, vz integer, time integer);"
    //data_cmd内容格式参考:"insert into table values(123456789, 'U', 'T', 100, 200, 50, 10, 5, 30, 25);"
    int ret = 0;
    char* err_msg = NULL;
    ret = sqlite3_exec(db, data_cmd, NULL, NULL, &err_msg);
    if (ret)
    {
        int sqliteErrCode = sqlite3_errcode(db);
        DBUG_SHOW("insert value to table err: code=%d, msg='%s'!\n", sqliteErrCode, err_msg);
        sqlite3_free(err_msg);
        return -1;
    }
    DBUG_SHOW("insert value to table successfully!\n");


    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1844454.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蓝牙模块在车载系统中的应用与集成:现状、挑战与未来展望

随着科技的快速发展,蓝牙技术已经深入到我们生活的方方面面,其中车载系统中的应用尤为显著。蓝牙模块作为一种无线通信技术,不仅为驾驶者提供了更加便捷的操作体验,同时也提升了驾驶的安全性。本文旨在分析蓝牙模块在车载系统中的…

计算机网络知识点汇总(二)

计算机网络知识点汇总 第1章计算机网络体系结构 1.1 计算机网络概述 1.1.1 计算机网络的概念 ​ 计算机网络是由若干个结点(node)和连接这些结点的链路(link)组成。网络中的结点可以是就三级、集线器、交换机、或者路由器等,网络之间通过路由器进行互联&#xf…

基于Java的家政服务管理平台

开头语:你好呀,我是计算机学姐码农小野!如果有相关需求,可以私信联系我。 开发语言:Java 数据库:MySQL 技术:B/S结构,SpringBoot框架 工具:MyEclipse,Nav…

在编译内核时添加驱动的固件

最近调驱动时,无法正常加载引导。 使用的内核5.10 内核启动先于文件系统,内核启动时驱动无法访问固件文件,所以无法加载驱动。 有2个办法,可以解决,一是驱动编译KO模块,系统启动后,再动态加载…

小林图解系统-二.硬件结构 2.6什么是软中断?

中断是什么? 中断是系统用来响应硬件设备请求的一种机制,操作系统收到硬件的中断请求,会打断正在执行的进程,然后调用内核中的中断处理程序来相应请求。 中断好比外卖打电话,打了电话可以停下手中的事情 中断是一种…

Qt项目学习-20240617

Qt项目学习 1.0 文件构建 1.1 预处理命令 C预处理命令是编译过程中的第一步,发生在编译器进行实际编译之前。预处理器(preprocessor)执行这些命令,它们不是C语言的一部分,但对源代码的编译过程至关重要。以下是一些常…

【javascript】vsCode我常用的开发插件汇总

console-log – 此插件用于快捷键生成console,当然你也可以在其他模板中自定义快捷生成内容 CodeGeeX – 一个内嵌在vscode插件列中的AI工具,让我们可以直接获取AI信息而不必麻烦的到其他AI软件或平台搜索,我经常用来查询TS定义类型相关的警告,效率坐火…

Window使用Hyper-V进行显卡直通

一、环境配置 处理器 Intel Xeon CPU E5-2680 v3 @ 2.50GHz 2.50 GHz 机带 RAM 64.0 GB 二、安装Hyper-V 控制面板–>程序和功能->启用或关闭winodws功能 三、打开Hyper-V安装windows 安装windows略过,记住(禁用检查点) 四、在本机Winows上以及管理员打开Powe…

【Java】线程池技术(二)ThreadPoolExecutor的基本定义

线程池初始化与定义 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)线程池构造方法的入参含义分别如下&…

【CRASH】freelist异常导致的异常地址访问

freelist异常导致的异常地址访问 问题现象初步分析继续深入新的发现沙盘推演寻找元凶分析代码后记 问题现象 项目一台设备几天内出现了两次crash&#xff0c;都是异常地址访问导致。 [66005.261660] BUG: unable to handle page fault for address: ffffff8881575110初步分析…

【星环社区版TDH2024年度大事件】全新版本?全新组件?性能提升10倍?

TDH社区版家族迎来新成员 不知不觉社区版已经陪伴大家将近两年的时间了&#xff0c;在这两年里收获到了很多认可&#xff0c;同时也收获到了一些建议与意见&#xff0c;比如资源成本的问题。在去年我们发布了TDH社区开发版&#xff0c;仅需单台服务器即可一键安装部署Inceptor…

链表OJ

GDUFE 在期末前再刷一次链表题 ~ 203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* removeElements(struct ListNode* head, int …

互联网应用主流框架整合之Spring Boot基本概念

Spring Boot是用来简化Spring应用程序的搭建、开发、测试和部署过程的&#xff0c;该框架使用了特定的方式进行配置&#xff0c;从而使开发人员不再需要定义样板化的配置&#xff0c;SpringBoot致力于快速应用开发(Rapid Application Development)领域的发展&#xff0c;它通过…

代码随想录训练营Day 63|力扣42. 接雨水、84.柱状图中最大的矩形

1.接雨水 代码随想录 代码&#xff1a;(单调栈) class Solution { public:int trap(vector<int>& height) {int result 0;stack<int> st;st.push(0);for(int i 1; i < height.size(); i){if(height[i] < height[st.top()]){st.push(i);}else if(heigh…

六西格玛目标设定的时候需要考虑哪些因素?

在追求企业卓越绩效的道路上&#xff0c;六西格玛管理方法论以其严谨的数据驱动和持续改进的理念&#xff0c;成为众多企业的首选工具。然而&#xff0c;要想真正发挥六西格玛的潜力&#xff0c;合理而精准的目标设定至关重要。那么&#xff0c;六西格玛目标设定的时候需要考虑…

新火种AI|英伟达市值超越微软!AI技术如何重塑科技股价值?

作者&#xff1a;一号 编辑&#xff1a;美美 AI&#xff0c;正带着美股狂奔。 2024年&#xff0c;英伟达&#xff08;NVIDIA&#xff09;以其在人工智能&#xff08;AI&#xff09;领域的卓越表现&#xff0c;市值首次超越了科技巨头微软&#xff0c;成为全球市值最高的公司…

变压器电机绕组阻值测试

产品概述 武汉凯迪正大变压器直流电阻的测量是变压器制造中半成品、成品出厂试验、安装、交接试验及电力部门预防性试验项目&#xff0c;能有效发现变压器线圈的选材、焊接、连接部位松动、缺股、断线等制造缺陷和运行后存在的隐患。KDZRS-20A直流电阻测试仪是测量变压器、互感…

XGBOOST案例

最近我在Kaggle上找到一个跟XGBOOST相关的代码&#xff0c;这有助于我们去实战性的学习。 这段代码旨在使用XGBoost和TPU进行大规模的分子绑定预测。 比赛项目&#xff1a;NeurIPS 2024 - Predict New Medicines with BELKA | Kaggle 训练样本代码&#xff1a; 上图是我们已…

ElasticSearch学习笔记(二)文档操作、RestHighLevelClient的使用

文章目录 前言3 文档操作3.1 新增文档3.2 查询文档3.3 修改文档3.3.1 全量修改3.3.2 增量修改 3.4 删除文档 4 RestAPI4.1 创建数据库和表4.2 创建项目4.3 mapping映射分析4.4 初始化客户端4.5 创建索引库4.6 判断索引库是否存在4.7 删除索引库 5 RestClient操作文档5.1 准备工…

怎么把答案去掉打印?超详细步骤告诉你!

在数字化教育日益普及的今天&#xff0c;我们时常需要在电子试卷和纸质试卷之间进行转换。然而&#xff0c;许多时候我们并不需要答案部分&#xff0c;这就需要我们掌握一些工具来去除答案&#xff0c;以便打印出纯净的试卷。本文将为您详细介绍如何使用试卷星、拍试卷以及WPS …