Android:SQLite(ORMLite)事务隔离级别
我在我的Android项目中使用ORMLite。 我知道Sqlite处理文件级锁定。 许多线程可以读取,可以写入。 锁可防止一次以上的写作。 任何人都可以请解释一下,如果一个线程正在更新一些记录,而另一个线程正在尝试读取该记录,会发生什么? 线程(即试图读取)是否会获得过时的数据? 还是会锁定,直到第一个线程完成其写入操作? 据我所知,有4个事务隔离级别:可串行化,可重复读取,已提交读取,未提交读取。 有没有办法在SQLite或ORMLite中进行更改?
SQLite有5个不同的锁定级别 - http://www.sqlite.org/lockingv3.html:解锁,共享,保留,挂起,独占。 这个问题的重要锁是共享锁:
“共享 - 数据库可能被读取但没有被写入,任何数量的进程可以同时持有SHARED锁,因此可以有多个同时读取的数据库,但是没有其他线程或进程被允许写入数据库文件,更多SHARED锁被激活。“
这些锁是表级别的(所以在DB中使用单行进行操作时 - 整个表都被锁定)。
因此,当您选择数据时,不允许其他进程更改数据。 读取数据的锁定步骤如下:解锁→挂起→共享→解除锁定(您可以在事务中运行选择)。 所以在你选择某个东西的时候,有人会改变数据不会发生。
你的问题是如果你正在更新数据库并在同一张表上做一个选择会发生什么。 在自动提交模式下,用于写入/更新的锁机制是:解锁→挂起→共享→保留→挂起→独占→解锁。 在排他锁中,没有新的读取器(连接)可以连接到数据库。 一次只能有一个EXCLUSIVE锁。 然后,SQLite将等待,直到读取连接的所有其他PENDING锁都被释放,并且会阻止任何新的锁。 目前,它将开始写入数据。
所以,我的答案是 - 只要更新过程没有完成,您的其他过程当然会得到旧数据。 请务必在事务中运行更新,以免数据不一致。 SQLite符合ACID标准,所以不应该发生部分更新和数据加密的情况。
关于此的一本很好的书是“SQLite权威指南”,特别是“交易”章节。
SQLite支持几种不同的隔离级别,可以在编译时和运行时选择。
http://www.sqlite.org/threadsafe.html
我认为默认情况下,Android的SQLite处于序列化模式。 就多线程访问而言,它在文件系统级别进行读/写锁定,以允许多个读取器,但一次只允许一个写入器:
http://www.sqlite.org/faq.html#q5
然而,ORMLite 强烈建议,并极力维持到数据库的连接,从而锁定问题可能不相关。
更具体地说,如果一个线程正在更新记录和另一个线程读取,那么这是一个竞争条件。 读取线程将在更新之前或更新完成后获取记录。 但是,读者不会获得部分更新的数据。 但我怀疑你知道这一点。
就SQLite支持的隔离级别而言,缺省值如前所述是序列化的,但它看起来像支持至少在某种程度上的读取未提交。
http://www.sqlite.org/sharedcache.html
你可以使用ORMLite的Dao.executeRaw()方法来启用它:
dao.executeRaw("PRAGMA read_uncommitted = True;");
但是,我对此没有任何经验,我也不确定它是否会为您在更新的行的一致视图(如果它在同一个查询中多次访问)提供一致的视图。 在写入事务期间,它可能与更一致的视图有关。
在阅读了这个类似的问题之后,我不确定如果在同一个查询中访问多次,就可以保证表中一行的相同视图。
链接地址: http://www.djcxy.com/p/64255.html