我知道事务应该强制执行ACID属性,但是SQLite中的w.r.t事务,a guy here警告在同一连接上完成的事务对其他人可见:
默认情况下 - 在单个事务中进行的更改 SQLite数据库连接可以对其他事务可见 那个连接立刻 - 甚至在打电话之前
SQLiteDatabase.endTransaction()
在媒体上,因为没有人指出,似乎是真实的建议。
现在,我正在阅读enableWriteAheadLogging()
作为官方文档并发Db访问的解决方案,并发现:
此方法可以并行执行多个查询 同一数据库上的线程。它是通过打开多个来实现的 连接到数据库并使用不同的数据库连接 对于每个查询。数据库日志模式也更改为启用 写入与读取同时进行。
如果未启用预写日志记录(默认值),则无法在数据库上进行读写操作 时间。在修改数据库之前,编写者隐式地获取了一个 数据库上的独占锁定,阻止读者访问 数据库直到写完成。
相比之下 启用预写日志记录(通过调用此方法),写入 操作发生在单独的日志文件中,该文件允许继续读取 同时。写入正在进行中,读者在其他线程上 将在写入之前感知数据库的状态 开始了。当写完成时,其他线程上的读者将会 感知数据库的新状态。
现在,如果您阅读上面突出显示的部分,您会看到默认情况下,未启用预写日志记录,默认行为会阻止并发读/写访问和阻塞,直到当前操作完成。如果你将它与上面所说的内容进行对比,似乎在交易时,没有这样的阻止。
非事务性行为如何阻止您读取或写入Db,但事务性行为会如何?
答案 0 :(得分:0)
没有“非 - transactional behaviour”:
除了在事务中,不能对数据库进行任何更改。更改数据库的任何命令(基本上,除SELECT之外的任何SQL命令)将自动启动事务(如果尚未生效)。最后一个查询完成后,将提交自动启动的事务。
那家伙所说的在技术上是错误的;没有“该连接上的其他交易”。 连接只能同时有一个活动事务。
当多个线程共享同一连接时,它们共享该事务。 而且因为它们处于同一个交易中,所以它们并不是相互隔离的。任何执行BEGIN / COMMIT / ROLLBACK或任何其他SQL语句的线程都会影响同一连接上的所有其他线程。
答案 1 :(得分:0)
默认情况下 - 在单个事务中进行的更改 SQLite数据库连接可以对其他事务可见 那个连接立刻 - 甚至在打电话之前 SQLiteDatabase.endTransaction()
你可能正在阅读(有意识的惩罚)更多的内容。即所应用的更改将可用,即它们可以在 BUT 连接中查看/读取它们尚未写入/提交。
仅在/如果
时 a)外部 AND ALL 内部/嵌套事务已被setTransactionSucccessful
AND
b)调用endTransaction
提交更改(写入磁盘)。即,仅在END处/期间将数据写入磁盘。