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

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

相关推荐
__Benco3 分钟前
OpenHarmony平台驱动使用(十五),SPI
人工智能·驱动开发·harmonyos
暗雨27 分钟前
封装一个 auth 工具
harmonyos
ChinaDragon40 分钟前
HarmonyOS:进度条 (Progress)
harmonyos
半路下车1 小时前
【Harmony OS 5】DevEco Testing赋能智慧教育
harmonyos·arkts
libo_20251 小时前
HarmonyOS5 灰度发布:通过AGC控制台分阶段更新Uniapp混合应用
harmonyos
libo_20251 小时前
自动化测试:将Uniapp页面注入HarmonyOS5 UITest框架
harmonyos
libo_20251 小时前
HarmonyOS5 Uniapp+OpenHarmony标准设备适配指南
harmonyos
libo_20251 小时前
HarmonyOS5 内存优化:用DevEco Studio Profiler分析Uniapp混合栈泄漏
harmonyos
libo_20251 小时前
AI能力整合:在Uniapp中调用HarmonyOS5 HiAI Kit的图像识别
harmonyos