sqlite叶连接打开(mono.data.sqlite.dll)



我正在使用此库使用Mono查询SQLite数据库:

https://www.mono-project.com/docs/database-access/providers/sqlite/

这就是我使用库的方式:

var dbLocation = "/var/log/asterisk/master.db";
var conString = $"Data Source={dbLocation}; Read Only=True; Pooling=True;";
using (var sqlite3 = new Mono.Data.Sqlite.SqliteConnection(conString)
{
       try
       {
                 sqlite3.Open();
                 // query database
                 using(var command = sqlite3.CreateCommand()){
                     command.CommandText = "select * from foo";
                     var reader = command.ExecuteReader();
                     // etc...
                     reader.Close(); // close reader
                 }
        }
        catch
        {
                     // log error
        }

}

请注意,此代码每秒执行每秒。另一个过程(星号(正在写入数据库,而我的过程是从数据库中读取。我无法打开连接,因为如果我这样做,星号将无法写入该数据库。因此,我必须每次打算查询数据库时打开并关闭连接。

此代码效果很好!我可以在仅读取模式下查询数据库。我基于此链接创建了连接字符串:

http://docs.go-mono.com/?link=t:mono.data.sqlite.sqliteconnection

此代码效果很好,但是2天后,我的程序崩溃了,因为sqlite.dll无法正确处理连接。sqlite.dll将连接打开,这是证明:

我应用程序的过程ID是29140:

然后,我运行了命令lsof -a -p 29140,然后将我返回这样的东西:
COMMAND   PID USER   FD   TYPE  DEVICE SIZE/OFF     NODE NAME
Main    29140 root  cwd    DIR     8,1     4096 46137345 /root
Main    29140 root  rtd    DIR     8,1     4096        2 /
Main    29140 root  txt    REG     8,1  3845024 12586404 /usr/bin/mono-sgen
Main  ........
... etc
.... etc
Main    29140 root   74r   REG     8,1 39170048 49023734 /var/log/asterisk/master.db
Main    29140 root   75r   REG     8,1 39170048 49023734 /var/log/asterisk/master.db
Main    29140 root   76r   REG     8,1 39170048 49023734 /var/log/asterisk/master.db
Main    29140 root   77r   REG     8,1 39170048 49023734 /var/log/asterisk/master.db
Main    29140 root   78r   REG     8,1 39170048 49023734 /var/log/asterisk/master.db
Main    29140 root   79r   REG     8,1 39170048 49023734 /var/log/asterisk/master.db
Main    29140 root   80r   REG     8,1 39170048 49023734 /var/log/asterisk/master.db
Main    29140 root   81r   REG     8,1 39170048 49023734 /var/log/asterisk/master.db
Main    29140 root   82r   REG     8,1 39170048 49023734 /var/log/asterisk/master.db
Main    29140 root   83r   REG     8,1 39170048 49023734 /var/log/asterisk/master.db
Main    29140 root   84r   REG     8,1 39170048 49023734 /var/log/asterisk/master.db
Main    29140 root   85r   REG     8,1 39170048 49023734 /var/log/asterisk/master.db

因为我每秒都会查询数据库,所以我希望每秒为/var/log/asterisk/master.db创建一个"文件锁"。这是随机发生的!如果数据库经常使用,我会发现/var/log/asterisk/master.db的数量有所增加。我如何正确处理此Sqlite连接?

我尝试过的东西:

呼叫GC.Collect()GC.WaitForPendingFinalizers()作为答案建议:https://stackoverflow.com/a/8513453/637142

我将连接字符串更改为:( poling = false (

var conString = $"Data Source={dbLocation}; Read Only=True; Pooling=False;";

我也关闭了读者:

    // using very important!
    using(var command = sqlite3.CreateCommand())
    {
                 command.CommandText = "select * from foo";
                 var reader = command.ExecuteReader();
                 // etc...
                 reader.Close(); // close reader! <----- this is very important for some reason
    }

这已经运行了一个小时,而且计数没有增加。我希望这是解决方案。

最新更新