SQLite 数据库具备事务处理能力。
事务本质上是一组操作的集合,它具有原子性,意味着这一系列操作要么全部成功执行,要么全部失败,不存在部分操作成功而部分失败的中间状态。
以常见的转账功能为例,A 账户向 B 账户转账一般包含两个独立步骤:先从 A 账户扣除相应金额,再将同等金额存入 B 账户。在没有事务保障的情况下,这两个独立操作可能出现不一致的结果,比如 A 账户扣钱成功,但 B 账户却未收到款项,这种情况会严重影响系统数据的准确性和业务的正常运行。而事务机制就能很好地解决这个问题,当某个操作失败时,它可以将所有操作回滚到初始状态,确保数据的一致性和完整性。
在鸿蒙开发中,rdbStore
提供了 beginTransaction()
和 rollBack()
方法来实现事务,从而保证操作的原子性。下面通过一个具体的代码案例来详细展示如何在鸿蒙中使用事务。
代码案例
- 配置数据库创建表单
// 配置数据库
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}`);
})
}
- 开启事务…
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();
}
}
代码解释
-
数据库配置与打开:
- 首先,定义了一个
RdbStoreConfig
对象,用于配置数据库的名称、安全级别和是否加密。 - 然后,使用
RdbStore.getRdbStore()
方法打开数据库,并在回调函数中创建了一个名为test_table
的表。
- 首先,定义了一个
-
事务操作:
- 调用
beginTransaction()
方法开启一个事务。 - 执行删除操作,将
test_table
表中name
为harmony
的记录删除。 - 通过
isError
变量模拟错误情况,如果isError
为true
,则抛出一个异常,中断事务的执行。 - 如果没有异常,执行插入操作,向
test_table
表中插入一条name
为wy
的记录。 - 调用
commit()
方法提交事务。
- 调用
-
异常处理与回滚:
- 如果在事务执行过程中出现异常,会捕获该异常并在
catch
代码块中调用rollBack()
方法回滚事务,将数据库状态恢复到事务开始前的状态。
- 如果在事务执行过程中出现异常,会捕获该异常并在
通过这种方式,确保了删除和插入操作要么全部成功,要么全部失败,实现了操作的原子性。