HarmonyOS 鸿蒙Next 通过taskpool操作数据库怎么实现同步?

发布于 1周前 作者 vueper 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 通过taskpool操作数据库怎么实现同步?

通过taskpool操作数据库怎么实现同步?有实现的例子吗?

4 回复

1、relationalStore (关系型数据库)支持在taskpool使用,但是获取getRdbStore所需要的context参数一般在主线程获取

2、同时需要确保任务函数入参满足序列化支持的类型,并且使用装饰器[@Concurrent](/user/Concurrent)标注。

参考代码来自官网文档:

// Index.ets
import { relationalStore, ValuesBucket } from '@kit.ArkData';
import { taskpool } from '@kit.ArkTS';

@Concurrent
async function create(context: Context) {
  const CONFIG: relationalStore.StoreConfig = {
    name: "Store.db",
    securityLevel: relationalStore.SecurityLevel.S1,
  };

  // 默认数据库文件路径为 context.databaseDir + rdb + StoreConfig.name
  let store: relationalStore.RdbStore = await relationalStore.getRdbStore(context, CONFIG);
  console.info(`Create Store.db successfully!`);

  // 创建表
  const CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS test (" +
    "id INTEGER PRIMARY KEY AUTOINCREMENT, " +
    "name TEXT NOT NULL, " +
    "age INTEGER, " +
    "salary REAL, " +
    "blobType BLOB)";
  await store.executeSql(CREATE_TABLE_SQL);
  console.info(`Create table test successfully!`);
}

@Concurrent
async function insert(context: Context, valueBucketArray: Array<relationalStore.ValuesBucket>) {
  const CONFIG: relationalStore.StoreConfig = {
    name: "Store.db",
    securityLevel: relationalStore.SecurityLevel.S1,
  };

  // 默认数据库文件路径为 context.databaseDir + rdb + StoreConfig.name
  let store: relationalStore.RdbStore = await relationalStore.getRdbStore(context, CONFIG);
  console.info(`Create Store.db successfully!`);

  // 数据插入
  await store.batchInsert("test", valueBucketArray as Object as Array<relationalStore.ValuesBucket>);
}

@Concurrent
async function query(context: Context): Promise<Array<relationalStore.ValuesBucket>> {
  const CONFIG: relationalStore.StoreConfig = {
    name: "Store.db",
    securityLevel: relationalStore.SecurityLevel.S1,
  };

  // 默认数据库文件路径为 context.databaseDir + rdb + StoreConfig.name
  let store: relationalStore.RdbStore = await relationalStore.getRdbStore(context, CONFIG);
  console.info(`Create Store.db successfully!`);

  // 获取结果集
  let predicates: relationalStore.RdbPredicates = new relationalStore.RdbPredicates("test");
  let resultSet = await store.query(predicates);  // 查询所有数据
  console.info(`Query data successfully! row count:${resultSet.rowCount}`);
  let index = 0;
  let result = new Array<relationalStore.ValuesBucket>(resultSet.rowCount)
  resultSet.goToFirstRow()
  do {
    result[index++] = resultSet.getRow()
  } while (resultSet.goToNextRow());
  resultSet.close();
  return result
}

@Concurrent
async function clear(context: Context) {
  const CONFIG: relationalStore.StoreConfig = {
    name: "Store.db",
    securityLevel: relationalStore.SecurityLevel.S1,
  };

  // 默认数据库文件路径为 context.databaseDir + rdb + StoreConfig.name
  await relationalStore.deleteRdbStore(context, CONFIG);
  console.info(`Delete Store.db successfully!`);
}

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';

  build() {
    RelativeContainer() {
      Text(this.message)
        .id('HelloWorld')
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
        .onClick(async () => {
          let context = getContext(this);

          // 数据准备
          const count = 5
          let valueBucketArray = new Array<relationalStore.ValuesBucket>(count);
          for (let i = 0; i < count; i++) {
            let v : relationalStore.ValuesBucket = {
              id: i,
              name: "zhangsan" + i,
              age: 20,
              salary: 5000 + 50 * i
            };
            valueBucketArray[i] = v;
          }
          await taskpool.execute(create, context)
          await taskpool.execute(insert, context, valueBucketArray)
          let index = 0
          let ret = await taskpool.execute(query, context) as Array<relationalStore.ValuesBucket>
          for (let v of ret) {
            console.info(`Row[${index}].id = ${v.id}`)
            console.info(`Row[${index}].name = ${v.name}`)
            console.info(`Row[${index}].age = ${v.age}`)
            console.info(`Row[${index}].salary = ${v.salary}`)
            index++
          }
          await taskpool.execute(clear, context)
        })
    }
    .height('100%')
    .width('100%')
  }
}

链接:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/batch-database-operations-guide-V5#%E4%BD%BF%E7%94%A8taskpool%E8%BF%9B%E8%A1%8C%E9%A2%91%E7%B9%81%E6%95%B0%E6%8D%AE%E5%BA%93%E6%93%8D%E4%BD%9C)

这个有同步问题吧?数据库读取是线程安全的?

鸿蒙的关系型数据库支持多种并发控制机制,如WAL(Write Ahead Log)模式和不同的锁机制,这些通常足以确保数据库操作的线程安全。 此外,鸿蒙的关系型数据库同一时间只能支持一个写操作,这表明系统已经内置了写锁机制,防止多个线程同时进行写操作导致的数据冲突。 参考链接:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/data-persistence-by-rdb-store-V5#约束限制

在HarmonyOS鸿蒙Next系统中,通过taskpool操作数据库实现同步,可以遵循以下专业步骤:

首先,明确taskpool是用于并发执行任务的机制,而数据库操作往往需要考虑数据一致性和线程安全。为实现同步,需确保数据库操作在特定任务执行完成后按顺序进行。

  1. 任务定义:在taskpool中定义数据库操作任务,包括读、写、更新等,确保每个任务都是独立的、可执行的函数。

  2. 任务依赖:如果任务之间存在依赖关系,利用taskpool的依赖管理功能,确保依赖任务先执行。

  3. 同步机制:采用互斥锁(mutex)、信号量(semaphore)等同步机制,保护数据库操作的关键区域,防止数据竞争和不一致。

  4. 任务回调:利用taskpool提供的回调机制,在任务完成后执行特定操作,如更新UI、记录日志等,确保操作顺序。

  5. 错误处理:为每个任务添加错误处理逻辑,捕获并处理数据库操作中的异常,确保系统稳定性。

通过上述步骤,可以在HarmonyOS鸿蒙Next系统中,通过taskpool实现数据库操作的同步。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html。

回到顶部