鸿蒙开发中,数据持久化之Transaction(事务)的概念及应用

SQLite 数据库具备事务处理能力。
事务本质上是一组操作的集合,它具有原子性,意味着这一系列操作要么全部成功执行,要么全部失败,不存在部分操作成功而部分失败的中间状态。

以常见的转账功能为例,A 账户向 B 账户转账一般包含两个独立步骤:先从 A 账户扣除相应金额,再将同等金额存入 B 账户。在没有事务保障的情况下,这两个独立操作可能出现不一致的结果,比如 A 账户扣钱成功,但 B 账户却未收到款项,这种情况会严重影响系统数据的准确性和业务的正常运行。而事务机制就能很好地解决这个问题,当某个操作失败时,它可以将所有操作回滚到初始状态,确保数据的一致性和完整性。

在鸿蒙开发中,rdbStore 提供了 beginTransaction()rollBack() 方法来实现事务,从而保证操作的原子性。下面通过一个具体的代码案例来详细展示如何在鸿蒙中使用事务。

代码案例

  • 配置数据库创建表单
async 复制代码
    // 配置数据库
    const STORE_CONFIG: relationalStore.StoreConfig = {
      name: "RdbTest.db",
      securityLevel: relationalStore.SecurityLevel.S1
    };

    relationalStore.getRdbStore(getContext(), STORE_CONFIG).then(async (rdbStore: relationalStore.RdbStore) => {
      this.rdbStore = rdbStore;
      // 创建表
      rdbStore.executeSql('CREATE TABLE IF NOT EXISTS test_table (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)');

      console.info(TAG, 'Get RdbStore successfully.')
    }).catch((err: BusinessError) => {
      console.error(TAG, `Get RdbStore failed, code is ${err.code},message is ${err.message}`);
    })
  }
  • 开启事务...
typescript 复制代码
  async beginTransaction() {
    try {
      // 开启事务
      (this.rdbStore as relationalStore.RdbStore).beginTransaction();
      //tablename与创建的表单名称一致
      let predicates = new relationalStore.RdbPredicates("test_table");
      predicates.equalTo("name", "harmony");

      (this.rdbStore as relationalStore.RdbStore).delete(predicates, (err, rows) => {
        if (err) {
          console.error(TAG, `Delete failed, code is ${err.code},message is ${err.message}`);
          return;
        }
        (this.rdbStore as relationalStore.RdbStore).commit();
        console.info(TAG, `Delete rows: ${rows}`);
      })

      // 模拟错误情况
      let isError = false; // 可修改为 true 来测试回滚
      if (isError) {
        throw new Error('人为制造异常,中断事务');
      }

      // 执行插入操作
      let valueBucket: relationalStore.ValuesBucket = {
        'id': 1001,
        'name': 'wy'
      };
      (this.rdbStore as relationalStore.RdbStore).insert("test_table", valueBucket).then((rowId: number) => {
        console.info(TAG, `Insert is successful, rowId = ${rowId}`);
        (this.rdbStore as relationalStore.RdbStore).commit()
      }).catch((err: BusinessError) => {
        console.error(TAG, `Insert is failed, code is ${err.code},message is ${err.message}`);
      })
    } catch (e) {
      console.error(TAG, '回滚 rollBack');
      (this.rdbStore as relationalStore.RdbStore).rollBack();
    }
  }

代码解释

  1. 数据库配置与打开

    • 首先,定义了一个 RdbStoreConfig 对象,用于配置数据库的名称、安全级别和是否加密。
    • 然后,使用 RdbStore.getRdbStore() 方法打开数据库,并在回调函数中创建了一个名为 test_table 的表。
  2. 事务操作

    • 调用 beginTransaction() 方法开启一个事务。
    • 执行删除操作,将 test_table 表中 nameharmony 的记录删除。
    • 通过 isError 变量模拟错误情况,如果 isErrortrue,则抛出一个异常,中断事务的执行。
    • 如果没有异常,执行插入操作,向 test_table 表中插入一条 namewy 的记录。
    • 调用 commit() 方法提交事务。
  3. 异常处理与回滚

    • 如果在事务执行过程中出现异常,会捕获该异常并在 catch 代码块中调用 rollBack() 方法回滚事务,将数据库状态恢复到事务开始前的状态。

通过这种方式,确保了删除和插入操作要么全部成功,要么全部失败,实现了操作的原子性。

相关推荐
GitCode官方14 小时前
openPangu-2.0-Pro 模型及技术报告正式开源上线 AtomGit AI
人工智能·华为·开源·harmonyos·atomgit
想你依然心痛16 小时前
HarmonyOS 5.0智慧农业开发实战:构建分布式农业物联网与区块链农产品溯源系统
人工智能·分布式·物联网·区块链·智慧农业·harmonyos·开发实战
Kevin Wang72716 小时前
华为昇腾910B部署手册——课堂质量诊断
人工智能·华为
刹那芳华199218 小时前
STMF+ESP-S+MQTT协议连接华为云端(附踩坑记录)
java·struts·华为
想你依然心痛1 天前
ArkTS 布局系统概述——从线性到网格,掌握声明式 UI 的骨架艺术
harmonyos·arkts·flex弹性布局·声明式布局·grid网格布局·响应式适配·布局性能优化
程序员黑豆1 天前
鸿蒙应用开发:@Computed 装饰器详解与实战
前端·harmonyos
ldsweet1 天前
HarmonyOS NEXT 音频播放器开发:AVPlayer 封装、播放列表与后台播放实战
华为·音视频·harmonyos
qizayaoshuap1 天前
# 44号应用:标签管理 — Flex 流式标签与交互状态设计
华为·harmonyos
2601_960906721 天前
华为MateBook Pro S首发搭载麒麟XE90
华为·postgresql·sqlite·时序数据库·tdengine
哎呦喂我去去去1 天前
HarmonyOS SDK助力讯飞听见App能力建设
华为·harmonyos