我是SQL的新手,正在尝试读取正在构建的数据库,同时我有另一个进程正在对其进行写入。我严格阅读的是写过程未写的内容(在我的实际示例中)。
当我尝试从数据库中读取数据时,写入过程通常会停止并且数据库被锁定-我需要杀死R并重新启动它。
我有点直观地理解为什么这会有问题。但是似乎有些解决方法(“没有锁定”?)我无法弄清楚如何实现。
下面的MWE:运行第一个进程,然后开始另一个会话并尝试运行第二个进程几次:
1> library(dplyr)
1> library(RSQLite)
1> system("rm dummy.sqlite3")
1> db <- src_sqlite("dummy.sqlite3", create = T)
1> df = data.frame(x = rnorm(2),y = rnorm(2))
1> table = copy_to(db, df = df, temporary = FALSE)
1> #Write process
1> for (i in 1:1e6){
1+ x = data.frame(x = rnorm(1),y = rnorm(1))
1+ db_insert_into(con = db$con, table = 'df', values = x)
1+ }
然后在另一个会话中...
3> db <- src_sqlite("dummy.sqlite3", create = F)
3> df = tbl(db,'df')
3> x1<-filter(df, x>3)
3> collect(x1)
Source: local data frame [2 x 2]
x y
(dbl) (dbl)
1 3.445299 -0.2531794
2 3.235710 -1.2147918
3> library(dplyr)
3> library(RSQLite)
3> setwd('/home/andrew/Dropbox/weirding_data')
3> db <- src_sqlite("dummy.sqlite3", create = F)
3> df = tbl(db,'df')
Error in sqliteFetch(res, n = n) :
rsqlite_query_fetch: failed first step: database is locked
3> x1<-filter(df, x>3)
3> collect(x1)
Source: local data frame [3 x 2]
x y
(dbl) (dbl)
1 3.445299 -0.2531794
2 3.235710 -1.2147918
3 3.457522 0.9358973
3> library(dplyr)
3> library(RSQLite)
3> setwd('/home/andrew/Dropbox/weirding_data')
3> db <- src_sqlite("dummy.sqlite3", create = F)
3> df = tbl(db,'df')
3> x1<-filter(df, x>3)
3> collect(x1)
Source: local data frame [5 x 2]
x y
(dbl) (dbl)
1 3.445299 -0.2531794
2 3.235710 -1.2147918
3 3.457522 0.9358973
4 3.265626 -0.7512677
5 3.052190 -0.1328862
3> library(dplyr)
3> library(RSQLite)
3> setwd('/home/andrew/Dropbox/weirding_data')
3> db <- src_sqlite("dummy.sqlite3", create = F)
3> df = tbl(db,'df')
Error in sqliteFetch(rs, n = -1) :
rsqlite_query_fetch: failed first step: database is locked
3> x1<-filter(df, x>3)
3> collect(x1)
Error in sqliteFetch(res, n = n) :
rsqlite_query_fetch: failed first step: database is locked
在失败之前,它可以工作几次。
那么,我该如何读取正在写入的内容?为什么失败不是确定性的?如果查询提取的数据量与写入过程相同,那么写入速度将受到多大的影响?
最佳答案
SQLite始终锁定整个数据库。
如果您有多个数据库操作属于同一类,请考虑使用transactions,以免中间出现意外故障。
要允许并发读写,请启用WAL mode(但请注意缺点)。