我正试图创造一个“后备”。机制,它将允许进程获得对db文件的EXCLUSIVE锁定,如果失败 - 获得SHARED [= readonly]锁定。
这个想法是,一旦一个进程获得一个EXCLUSIVE锁,它就会在其中一个表中写下一些关于它自己的信息,所以一旦另一个进程试图获得一个EXCLUSIVE锁 - 它将会失败,但是能够执行& #39; SELECT'查询数据库。
我找到了following问题,这个问题只描述了答案的一半 - 我能够获得' EXCLUSIVE'锁定,但我没有找到一种获得“共享”的方法。锁。
伪代码:
try
{
OpenExclusive();
// Perform INSERT/UPDATE statements
}
catch(ExclusiveConnectionException)
{
OpenShared();
// Perform SELECT statements
}
答案 0 :(得分:1)
我最终只是通过使用交易来实现它,但首先要确保设置连接字符串' DefaultTimeout'值为' 0':
connection.ConnectionString = "Data Source=...;Version=3;DefaultTimeout=0"
这会阻止'连接。打开'悬挂声明。
connection.Open(); // Opens connection as SHARED
try
{
// Gain exclusive write-lock by beginning a transaction:
using (SQLiteCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "BEGIN IMMEDIATE";
cmd.ExecuteNonQuery();
}
}
catch(SQLiteException ex)
{
if (ex.ResultCode == SQLiteErrorCode.Busy)
{
// Connection is still open as read-only (can perform SELECT statements)
}
else
// Unexpected exception:
throw;
}
为了使数据保持同步,我们必须在每次写操作后执行COMMIT并重新启动事务:
using (SQLiteCommand cmd = connection.CreateCommand())
{
// Notice the 'COMMIT; BEGIN IMMEDIATE;' statements in the end:
cmd.CommandText = "INSERT INTO [SOME_TABLE] VALUES('foo','bar'); COMMIT; BEGIN IMMEDIATE;";
}