这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战
Transaction
Transaction是一个数据库概念,一般称之为「事务」。它的属性有四个:原子性(Atomicity) 、一致性(Consistency) 、隔离性(Isolation) 、持久性(Durability) ,缩写为ACID。
原子性是指:一个事务中做的任意多个操作就像是一个操作,要么成功,要么失败。成功表示所有操作执行完成,失败表示有的操作有些问题,失败后系统会将数据库状态回退到执行事务之前。利用这个属性可以很简单的解决数据库的读写冲突问题。
一致性是指:数据库在成功提交的事务上会正确地改变状态。
隔离性是指:事务的操作会相互独立和透明。这一点在Room中被屏蔽掉了,因为Room 一次最多只能执行一个事务,其他事务按先到先得的顺序排队和执行。
持久性是指:确保已提交事务的结果或效果在系统发生故障的情况下仍然存在。
实际上@Insert,@Update和@Delete是事务,以及在@Query中使用了Insert,Update或者Delete,这个@Query也是默认被@Transaction标注的。
这样的话,如果你的某个事务是比较耗时的,那你执行其他时候就得排队咯。
不过,你也可以利用这个特性,将一系列操作整合到一个事务中,例如一个先查再改再查的操作(以下是伪代码):
@Transaction
fun someOperation():Int{
val a = find1()
insert(a)
return find2()
}
复制代码
虽然协程也可以实现这种效果(前提给所有的操作函数加上suspend),但协程推荐的做法是可取消,而@Transaction保证了原子性。事实上,性能是没有任何区别的。
注:大概在2.2.6之后@Transaction函数前不能加suspend了,因为这样导致多个线程同时读写sqlite,导致死锁。
优化首次查询速度
第一次查询会慢一些,不管是一条还是 3000 条,其实可能大概需要 200ms 左右,这是 SQLite 的局限性...
解决方案:在客户无感知的时候先热启动 Sqlite 先查一条。