我对Android上的SQLite事务的理解主要基于this article。它的实质是
如果您没有在显式事务中包装对SQLite的调用,它将 为您创建一个隐式交易。这些的后果 隐式交易是速度的损失
。
这种观察是正确的-我开始使用事务来解决该问题:速度。在我自己的Android应用中,我使用许多相当复杂的SQLite表来存储通过SQLite JSON1 extension处理的JSON数据-我使用SQLCipher内置JSON1。
在任何给定时间,我都必须操作-插入,更新或删除-多个表中的行。考虑到JSON的复杂性,我将在为每个表操作创建的临时表的帮助下执行此操作。操纵的开始以SQL开头,
DROP TABLE IF EXISTS h1;
CREATE TEMP TABLE h1(v1 TEXT,v2 TEXT,v3 TEXT,v4 TEXT,v5 TEXT);
某些表只需要一个表-我通常将其称为h1-其他表则需要两个表,在这种情况下,我将它们称为h1和h2。
任何一组操作中的整个操作序列采用以下形式
begin transaction
manipulate Table 1 which
which creates its own temp tables, h1[h2],
then extracts relevant existing JSON from Table 1 into the temps
manipulates h1[h2]
performs inserts, updates, deletes in Table 1
on to the next table, Table 2 where the same sequence is repeated
continue with a variable list of such tables - never more than 5
end transaction
我的问题
DROP TABLE/CREATE TEMP TABLE
通话后会发生什么。如果我最终得到h1 [h2]个临时表,这些临时表在处理Table(n)时已预装了来自操纵Table(n-1)的数据,则对Table(n)的更新将完全出错。我假设我拥有的DROP TABLE
位正在解决这个问题。我猜对了吗?我必须承认自己不是SQL方面的专家,更不用说SQLite了,在使用事务时还是一个新手。 SQLite JSON扩展功能非常强大,但是在处理数据时引入了全新的复杂性。
答案 0 :(得分:1)
使用事务的主要原因是为了减少写入磁盘的开销。
因此,如果您没有在事务中包装多个更改(插入,删除和更新),则每个更改都会导致数据库写入磁盘以及相关的开销。
如果将它们包装在事务中,并且仅在事务完成时才写入内存版本(请注意,如果使用 SQLiteDatabase beginTransaction / endTransaction 方法,您应该在结束交易的过程中使用 setTransactionSuccessful 方法,然后使用 endTransaction 方法)。
也就是说,SQLiteDatabase方法与在开始事务然后结束/提交/然后通过纯SQL进行操作不同(即,否则SQLiteDatabase方法将自动回滚事务)。
说那句话:-
如果您没有在显式事务中包装对SQLite的调用,它将 为您创建一个隐式交易。这些的后果 隐式交易是速度的损失
基本上重申:-
任何更改数据库的命令(基本上是任何SQL命令) SELECT以外的其他选项)将自动开始一项交易 尚未生效。自动启动的交易是 最后一个查询完成时提交。
SQL As Understood By SQLite - BEGIN TRANSACTION,即不是特定于Android的。
这听起来像是做事的有效方法吗? 更好地将每个表操作包装在自己的事务中?
在单个事务中执行所有操作将更加高效,因为只有一次写入磁盘操作。
我不清楚我的DROP TABLE / CREATE TEMP TABLE发生了什么 电话。如果我最后得到的h1 [h2]临时表预先填充了 使用Table(n)时操作Table(n-1)的数据,然后 Table(n)上的更新将完全出错。我假设 我有DROP TABLE位正在处理此问题。我在吗 假设这个?
删除表将确保数据完整性(即,您应该这样做),也可以使用:-
CREATE TEMP TABLE IF NOT EXISTS h1(v1 TEXT,v2 TEXT,v3 TEXT,v4 TEXT,v5 TEXT);
DELETE FROM h1;