sqlite,从多个进程访问单个DB文件

时间:2018-04-20 19:29:14

标签: sqlite

我有一个设置从 ONE 进程向 OTHER 进程发送消息,发送方式由以下方式完成:

  1. 消息添加到 sqlite 数据库
  2. 消息发送到下一个流程
  3. sqlite 数据库中删除消息
  4. 为了测试我将4 过滤器和最终的服务器连接在一起,服务器将只回显消息...所有这些都有2x4 + 1 = 9插入在4 + 1 = 5个进程中在很短的时间内删除。所有5个进程使用带有私有数据库句柄的相同数据库。要完成至少一些步骤......对于每个新的 sql 操作,我打开关闭 db-handel。如果我不这样做,如果我不使用 WAL 事务格式,那么 sqlite 数据库总是会在两步之后失败。

    使其简短 sqlite 每次都失败... sqlite 可以执行几个步骤,但最终会在无限 SQLITE_BUSY 中结束。我尝试了很多不同的配置...我的最新的 pragma是:

    EXEC(4,"PRAGMA synchronous  = NORMAL    ;")
    EXEC(5,"PRAGMA journal_mode = WAL       ;")
    EXEC(6,"PRAGMA locking_mode = NORMAL    ;")
    

    典型的输出是:

    1. ft0-3 过滤器
    2. sv0 服务器
    3. transLId sqlite rowid
    4. db 是值班的数据库句柄
    5. ...示例

      ---- service-2-2-(1|binary|uds|c.uds.spawn) start
      S> {ft0         :pid(64414):tid(0x7f60eed77780):B:dlv(0):ctxId( 0):rc(2):ctx(0x24d17e0     ):pSqlInsertReadTrans }: START insert: db<(nil)>
      S> {ft0         :pid(64414):tid(0x7f60eed77780):B:dlv(0):ctxId( 0):rc(2):ctx(0x24d17e0     ):pSqlInsertReadTrans }: DONE  insert: db<0x24e0f98>, transLId<1>
      S> {ft1         :pid(64415):tid(0x7f62e168f780):B:dlv(0):ctxId( 0):rc(2):ctx(0x9fa650      ):pSqlInsertReadTrans }: START insert: db<(nil)>
      S> {ft1         :pid(64415):tid(0x7f62e168f780):B:dlv(0):ctxId( 0):rc(2):ctx(0x9fa650      ):pSqlInsertReadTrans }: DONE  insert: db<0xa096a8>, transLId<2>
      S> {ft2         :pid(64416):tid(0x7f4f3fa74780):B:dlv(0):ctxId( 0):rc(2):ctx(0x100a320     ):pSqlInsertReadTrans }: START insert: db<(nil)>
      S> {ft0         :pid(64414):tid(0x7f60eed77780):B:dlv(0):ctxId( 0):rc(2):ctx(0x24d17e0     ):pSqlDeleteReadTrans }: START delete: db<0x24e0328>, transLId<1>
      S> {ft2         :pid(64416):tid(0x7f4f3fa74780):B:dlv(0):ctxId( 0):rc(2):ctx(0x100a320     ):pSqlInsertReadTrans }: SQLITE_BUSY:  db<0x1018bc8>
      S> {ft0         :pid(64414):tid(0x7f60eed77780):B:dlv(0):ctxId( 0):rc(2):ctx(0x24d17e0     ):pSqlDeleteReadTrans }: DONE  delete: db<0x24e0328>, transLId<1>
      S> {ft2         :pid(64416):tid(0x7f4f3fa74780):B:dlv(0):ctxId( 0):rc(2):ctx(0x100a320     ):pSqlInsertReadTrans }: DONE  insert: db<0x1018bc8>, transLId<3>
      S> {ft3         :pid(64417):tid(0x7fbf3b3da780):B:dlv(0):ctxId( 0):rc(2):ctx(0x1fedff0     ):pSqlInsertReadTrans }: START insert: db<(nil)>
      S> {ft1         :pid(64415):tid(0x7f62e168f780):B:dlv(0):ctxId( 0):rc(2):ctx(0x9fa650      ):pSqlDeleteReadTrans }: START delete: db<0xa08d08>, transLId<2>
      S> {ft1         :pid(64415):tid(0x7f62e168f780):B:dlv(0):ctxId( 0):rc(2):ctx(0x9fa650      ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0xa08d08>
      S> {ft1         :pid(64415):tid(0x7f62e168f780):B:dlv(0):ctxId( 0):rc(2):ctx(0x9fa650      ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0xa08d08>
      S> {ft3         :pid(64417):tid(0x7fbf3b3da780):B:dlv(0):ctxId( 0):rc(2):ctx(0x1fedff0     ):pSqlInsertReadTrans }: DONE  insert: db<0x1ffc028>, transLId<4>
      S> {sv0         :pid(64418):tid(0x7f275dffc780):B:dlv(0):ctxId( 0):rc(2):ctx(0x2045be0     ):pSqlInsertReadTrans }: START insert: db<(nil)>
      S> {ft2         :pid(64416):tid(0x7f4f3fa74780):B:dlv(0):ctxId( 0):rc(2):ctx(0x100a320     ):pSqlDeleteReadTrans }: START delete: db<0x1017858>, transLId<3>
      S> {ft2         :pid(64416):tid(0x7f4f3fa74780):B:dlv(0):ctxId( 0):rc(2):ctx(0x100a320     ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0x1017858>
      S> {sv0         :pid(64418):tid(0x7f275dffc780):B:dlv(0):ctxId( 0):rc(2):ctx(0x2045be0     ):pSqlInsertReadTrans }: DONE  insert: db<0x204ec78>, transLId<5>
      S> {ft3         :pid(64417):tid(0x7fbf3b3da780):B:dlv(0):ctxId( 0):rc(2):ctx(0x1fedff0     ):pSqlDeleteReadTrans }: START delete: db<0x1ffb2a8>, transLId<4>
      S> {ft3         :pid(64417):tid(0x7fbf3b3da780):B:dlv(0):ctxId( 0):rc(2):ctx(0x1fedff0     ):pSqlDeleteReadTrans }: DONE  delete: db<0x1ffb2a8>, transLId<4>
      C> {ft3         :pid(64417):tid(0x7fbf3b3da780):B:dlv(0):ctxId( 0):rc(1):ctx(0x1ff4a60     ):pSqlInsertReadTrans }: START insert: db<(nil)>
      C> {ft3         :pid(64417):tid(0x7fbf3b3da780):B:dlv(0):ctxId( 0):rc(1):ctx(0x1ff4a60     ):pSqlInsertReadTrans }: DONE  insert: db<0x1ffe8c8>, transLId<6>
      S> {ft1         :pid(64415):tid(0x7f62e168f780):B:dlv(0):ctxId( 0):rc(2):ctx(0x9fa650      ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0xa08d08>
      S> {ft2         :pid(64416):tid(0x7f4f3fa74780):B:dlv(0):ctxId( 0):rc(2):ctx(0x100a320     ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0x1017858>
      S> {ft1         :pid(64415):tid(0x7f62e168f780):B:dlv(0):ctxId( 0):rc(2):ctx(0x9fa650      ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0xa08d08>
      S> {ft2         :pid(64416):tid(0x7f4f3fa74780):B:dlv(0):ctxId( 0):rc(2):ctx(0x100a320     ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0x1017858>
      S> {ft1         :pid(64415):tid(0x7f62e168f780):B:dlv(0):ctxId( 0):rc(2):ctx(0x9fa650      ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0xa08d08>
      S> {ft2         :pid(64416):tid(0x7f4f3fa74780):B:dlv(0):ctxId( 0):rc(2):ctx(0x100a320     ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0x1017858>
      S> {ft1         :pid(64415):tid(0x7f62e168f780):B:dlv(0):ctxId( 0):rc(2):ctx(0x9fa650      ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0xa08d08>
      S> {ft2         :pid(64416):tid(0x7f4f3fa74780):B:dlv(0):ctxId( 0):rc(2):ctx(0x100a320     ):pSqlDeleteReadTrans }: SQLITE_BUSY:  db<0x1017858>
      
        

      问题:任何想法都要进一步发展?

1 个答案:

答案 0 :(得分:0)

The first comment is my answer… using sqlite with a "#memdb#" is no problem… but… no persistance possible.

  # This fails with a FILE based database… "sqlite" is NOT able to share a database 
  # with multiple processes or threads
  test service-2-2-($I|$B|$C|$S) {mass "@" with TRANSACTION} \
      -setup {
        #set testdb  [file join . [file tail [MakeFile {} .dat]]]
        set testdb  "#memdb#"
        set CON1    [list {*}[FindFreeConnection $S] --storage $testdb]

        set cmd     [list {*}[getFilter Filter3.$S] --name "ft0" {*}$CON1 @]
        foreach i {1 2 3} {
          lappend cmd Filter3 --storage $testdb --name "ft$i" @
        }
        lappend cmd {*}[getServer $S] --storage $testdb --name "sv0"

        proc otFWRD {ctx} {
          $ctx Send "R" "I" [$ctx StorageCount]
        }
        set RET ""
        proc otRESU {ctx} {
          $ctx ReadT_START
          lappend ::RET [$ctx ReadC]
          $ctx ReadT_END
          lappend ::RET [$ctx ReadI]
        }
        Bg @stderr {*}$cmd
        foreach {FIRST CTX} [Create $I $CON1] break
      } \
      -body           {
        $CTX ServiceCreate FWRD otFWRD
        $CTX ServiceCreate RESU otRESU
        $CTX Send "T" RESU "FWRD:(C)" ident
        $CTX ProcessEvent -wait ONCE
        $CTX ProcessEvent -wait ONCE
        set RET
      } \
      -cleanup {
        rename $FIRST ""
      } \
      -returnCodes    ok \
      -result         "ident 1"