typescript - SQLite - 同一事务中的多个调用
问题描述
感谢您的关注 - 我正在使用 Typescript 编写前端 SPA。我正在使用电容器JS 来实现跨平台兼容性,并且我正在使用@capacitor-community/sqlite 插件。我是 SQLite 的新手,但不是一般的数据库。
通过在 SQLite 上使用特定的 API,这可能会变得复杂。
API 在这里:https ://github.com/capacitor-community/sqlite#supported-methods
无论如何,API 不符合我的期望。
我想要一种能够启动事务、进行多次调用并最终提交事务(或在错误处理程序中回滚)的模式。如果我可以在同一个 txn 内调用读取,或者至少能够在写入 txn 打开时在 txn外部进行读取,那就太好了。
看起来这个 (capacitor-community/sqlite) 包装器默认情况下在我所做的每个调用周围添加一个事务,除非我用 bool 参数覆盖。如果我覆盖,我负责将事务代码包含在 sql 语句块中。
我的第一个天真的方法是发出一个将启动事务的语句,然后它会进行额外的 api 调用,这些调用应该是 txn 的一部分,最后运行一个 sql 语句来commit
处理 txn。
例如
async Transaction(actions: () => Promise<void>): Promise<void> {
await SqliteService.Instance.db.execute('BEGIN TRANSACTION;',
try {
await actions();
await SqliteService.Instance.db.execute('COMMIT TRANSACTION;', false); //useTransaction = false
} catch (e) {
await SqliteService.Instance.db.execute('ROLLBACK TRANSACTION;', false); //useTransaction = false
throw e;
}
这根本不起作用。看起来像这样的状态并没有在通话之间保持。我认为有些事情(比如打开光标)会导致会话保持打开状态,但通常会话只会随着我对 API 的每次调用而打开和关闭。
我没有尝试过使用游标来保持交易开放,这似乎是一种反模式
当我仔细考虑时,似乎我可能必须在事务中发送一大块 SQL 才能让 SQLite 做我想做的事。
所以我正在考虑将我的 documentStore api 重写为,而不是直接调用 SQLite 来运行语句,而是当我想在单个事务中执行多项操作时,提供一个 sqlBuilder 类型的类。然后我可以将多个语句粘合在一起。
...
但是我喜欢当前的界面,并且重写我的 documentStore 上的“写入”方法以拥有一些 sqlBuilder 似乎是朝着不同方向迈出的一大步。例如
async Transaction(sqlBuilder: (builder: WriteSqlBuilder<T>) => {statement: string, values: unknown[]} []) {
...
我想知道 - 人们通常如何在单个事务中在 SQLite 中执行多个操作(查询、写入)?
谢谢!
解决方案
因此,这最终成为我使用的包装器中的一些特殊行为capacitor-community/sqlite
。
当调用 eg 时,executeSet({sql, params}[], transaction)
您可以传递一个布尔值来使用或不使用事务。这是一个帮手。此transaction
值默认为 true。当它设置为 true 时,包装库会自动为您添加BEGIN TRANSACTION
和COMMIT TRANSACTION
(并且ROLLBACK TRANSACTION
在出现错误的情况下)围绕您的 sql 项,所有这些都在单个调用中。
如果你显式设置transaction
为 false,它将像普通 SQLite 一样,为调用启动一个隐式事务,当调用完成时,这是最后一个 SQL 语句,隐式事务被隐式提交。
让我感到困惑的是我正在 Web 浏览器中进行开发工作(对于这个跨平台应用程序),所以我正在使用jeep-sqlite
. jeep-sqlite
使用内存中的 sqlite db,并有一种saveToStore(dbName)
方法将 SQLite 字节刷新到 IndexedDb 条目中。
我认为正在发生的事情是我在交易中间冲洗。刷新后,不再有活动事务。
最后,我使用async-lock
了对 SQLite db 包装器的访问权限,并拥有自己async Transaction(actions: () => Promise<void>)
处理 BEGIN/COMMIT/ROLLBACK 本身的方法,以及一些通用的 DocumentStore 方法,这些方法进行隐式调用,然后包含在事务中。
推荐阅读
- javascript - 不推荐使用正文解析器 undefined extended:提供扩展选项
- html - 用不确定的列数划分网格
- linux - Wildfly 服务无法启动
- java - 使用原子非阻塞方法与同步的单例
- angular - Angular4 http 重复调用
- javascript - Javascript:将项目插入数组的确切中心
- javascript - 未经我的许可,正在单击脚本中的按钮。JavaScript 琐事游戏
- redux - Redux 在使用 mapDispatchToProps 初始化之前无法访问 action creator
- amazon-web-services - AWS 无服务器:从无服务器迁移到 SAM
- javascript - 使用嵌套的 try-catch 块