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

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

相关推荐
桃子酱紫君2 小时前
华为配置篇-OSPF基础实验
华为
BRUCE_WUANG2 小时前
【不是广告】华为昇腾的一小步,Pytorch的一大步
人工智能·pytorch·华为
jian110582 小时前
鸿蒙Android4个脚有脚线
华为·harmonyos·鸿蒙
别说我什么都不会14 小时前
鸿蒙轻内核调测-内存调测-内存信息统计
操作系统·harmonyos
一个处女座的程序猿O(∩_∩)O16 小时前
鸿蒙与DeepSeek深度整合:构建下一代智能操作系统生态
华为·ai·wpf·harmonyos
一只小风华~18 小时前
鸿蒙(HarmonyOS) 自定义弹窗组件
笔记·华为·harmonyos
baobao熊18 小时前
【HarmonyOS Next】自定义Tabs
华为·harmonyos
李坤19 小时前
鸿蒙状态管理之State
前端·harmonyos
轻口味1 天前
【每日学点HarmonyOS Next知识】web滚动、事件回调、selectable属性、监听H5内部router、Grid嵌套时高度设置
前端·华为·harmonyos·arkts·harmonyosnext