鸿蒙开发中,数据持久化之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() 方法回滚事务,将数据库状态恢复到事务开始前的状态。

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

相关推荐
Huang兄10 小时前
鸿蒙-List和Grid拖拽排序:仿微信小程序删除效果
harmonyos·arkts·arkui
anyup1 天前
🔥2026最推荐的跨平台方案:H5/小程序/App/鸿蒙,一套代码搞定
前端·uni-app·harmonyos
Ranger09291 天前
鸿蒙开发新范式:Gpui
rust·harmonyos
Huang兄1 天前
鸿蒙-深色模式适配
harmonyos·arkts·arkui
SummerKaze3 天前
为鸿蒙开发者写一个 nvm:hmvm 的设计与实现
harmonyos
在人间耕耘5 天前
HarmonyOS Vision Kit 视觉AI实战:把官方 Demo 改造成一套能长期复用的组件库
人工智能·深度学习·harmonyos
王码码20355 天前
Flutter for OpenHarmony:socket_io_client 实时通信的事实标准(Node.js 后端的最佳拍档) 深度解析与鸿蒙适配指南
android·flutter·ui·华为·node.js·harmonyos
HarmonyOS_SDK5 天前
【FAQ】HarmonyOS SDK 闭源开放能力 — Ads Kit
harmonyos
Swift社区5 天前
如何利用 ArkUI 框架优化鸿蒙应用的渲染性能
华为·harmonyos
特立独行的猫a5 天前
uni-app x跨平台开发实战:开发鸿蒙HarmonyOS影视票房榜组件完整实现过程
华为·uni-app·harmonyos·轮播图·uniapp-x