SQlite交易:更改可见性

时间:2017-10-22 11:51:25

标签: android sqlite transactions

我知道事务应该强制执行A​​CID属性,但是SQLite中的w.r.t事务,a guy here警告在同一连接上完成的事务对其他人可见:

  

默认情况下 - 在单个事务中进行的更改   SQLite数据库连接可以对其他事务可见   那个连接立刻 - 甚至在打电话之前   SQLiteDatabase.endTransaction()

在媒体上,因为没有人指出,似乎是真实的建议。

现在,我正在阅读enableWriteAheadLogging()作为官方文档并发Db访问的解决方案,并发现:

  

此方法可以并行执行多个查询   同一数据库上的线程。它是通过打开多个来实现的   连接到数据库并使用不同的数据库连接   对于每个查询。数据库日志模式也更改为启用   写入与读取同时进行。

     

如果未启用预写日志记录(默认值),则无法在数据库上进行读写操作   时间。在修改数据库之前,编写者隐式地获取了一个   数据库上的独占锁定,阻止读者访问   数据库直到写完成。

     

相比之下   启用预写日志记录(通过调用此方法),写入   操作发生在单独的日志文件中,该文件允许继续读取   同时。写入正在进行中,读者在其他线程上   将在写入之前感知数据库的状态   开始了。当写完成时,其他线程上的读者将会   感知数据库的新状态。

现在,如果您阅读上面突出显示的部分,您会看到默认情况下,未启用预写日志记录,默认行为会阻止并发读/写访问和阻塞,直到当前操作完成。如果你将它与上面所说的内容进行对比,似乎在交易时,没有这样的阻止。

非事务性行为如何阻止您读取或写入Db,但事务性行为会如何?

2 个答案:

答案 0 :(得分:0)

没有“非 - transactional behaviour”:

  

除了在事务中,不能对数据库进行任何更改。更改数据库的任何命令(基本上,除SELECT之外的任何SQL命令)将自动启动事务(如果尚未生效)。最后一个查询完成后,将提交自动启动的事务。

那家伙所说的在技术上是错误的;没有“该连接上的其他交易”。 连接只能同时有一个活动事务。

当多个线程共享同一连接时,它们共享该事务。 而且因为它们处于同一个交易中,所以它们并不是相互隔离的。任何执行BEGIN / COMMIT / ROLLBACK或任何其他SQL语句的线程都会影响同一连接上的所有其他线程。

答案 1 :(得分:0)

  

默认情况下 - 在单个事务中进行的更改   SQLite数据库连接可以对其他事务可见   那个连接立刻 - 甚至在打电话之前   SQLiteDatabase.endTransaction()

你可能正在阅读(有意识的惩罚)更多的内容。即所应用的更改将可用,即它们可以在 BUT 连接中查看/读取它们尚未写入/提交。

仅在/如果

  • a)外部 AND ALL 内部/嵌套事务已被setTransactionSucccessful AND

    <标记为清洁/确定/ LI>
  • b)调用endTransaction

提交更改(写入磁盘)。即,仅在END处/期间将数据写入磁盘。