[英]SQLite and “Database is Locked”
使用SQLite,System.Data.SQLite和Dapper(在控制台应用程序中;更高版本的Windows Service;高吞吐量); 为什么仍然存在“数据库已锁定”?
我什至用这种方法抽象了对SQLite db的所有调用:
public static void LocalDbScope(Action<IDbConnection> action)
{
try
{
lock (DbLock)
{
using (var connection = Open(LocalStorageConnectionString))
{
action(connection);
}
}
}
catch (Exception xux)
{
ErrLog.Error(xux);
throw;
}
}
打开内存映射选项也无济于事:
connection.Execute("PRAGMA wal_autocheckpoint=32; PRAGMA journal_size_limit = 2048;");
connection.Execute("PRAGMA mmap_size=" + GB);
这是连接字符串:
var builder = new SQLiteConnectionStringBuilder
{
DataSource = storageDbFilePath,
FailIfMissing = false,
PageSize = 32 * KB,
CacheSize = 10 * MB,
ForeignKeys = false,
UseUTF16Encoding = false,
Pooling = true,
JournalMode = SQLiteJournalModeEnum.Wal,
SyncMode = SynchronizationModes.Normal,
DateTimeKind = DateTimeKind.Utc,
DateTimeFormat = SQLiteDateFormats.ISO8601,
DefaultIsolationLevel = IsolationLevel.ReadCommitted,
DefaultTimeout = (int)TimeSpan.FromMinutes(1).TotalMilliseconds
};
LocalStorageConnectionString = builder.ToString();
我在这里想念什么?
注意:当您在Google上搜索“数据库已锁定”时,所有排名靠前的结果(以及整个首页)都是关于此问题的不同编程语言和平台。 似乎还有一些关于SQLite的内容,我无法过滤掉这张图片。
如我的评论中所述,我不知道正在发生什么,而又看不到您的更多代码。
不过,如果您不愿意将Dapper更改为Sqlite-net,则下面是一个使用您的抽象的非阻塞小示例,该抽象不会引发任何异常。 希望它可以帮助您解决。
using System;
using System.Data;
using System.Data.SQLite;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Dapper;
namespace MyConsoleApplication
{
public class Program
{
static void Main(string[] args)
{
var test = new TestSQLite();
test.GoForIt();
}
}
public class Entity
{
public int Id { get; set; }
public string Content { get; set; }
}
public class TestSQLite
{
private const string ConnectionString = "Data Source=sqlitetest.sqlite";
private static readonly object DbLock = new object();
public void GoForIt()
{
CreateTable();
var random = new Random();
for (int i = 0; i < 100; i++)
{
if ( i % 2 != 0)
{
Task.Factory.StartNew(() => Thread.Sleep(random.Next(0, 200))).ContinueWith(other =>
LocalDbScope(action =>
{
var entity = new Entity {Content = "hoax"};
entity.Id = action.Query<int>(
@"insert into entity (content) values (@Content); select last_insert_rowid()",
entity).First();
var ids = action.Query<int>(@"select id from entity").ToList();
Console.WriteLine("Inserted id:{0}, all ids:[{1}]", entity.Id, string.Join(",", ids));
}));
}
else
{
Task.Factory.StartNew(() => Thread.Sleep(random.Next(200, 500))).ContinueWith(other =>
LocalDbScope(action =>
{
action.Execute(@"delete from entity");
Console.WriteLine("Deleted all entities");
}));
}
}
Console.ReadLine();
}
public static void LocalDbScope(Action<IDbConnection> action)
{
lock (DbLock)
{
using (var connection = new SQLiteConnection(ConnectionString))
action(connection);
}
}
private static void CreateTable()
{
using (IDbConnection c = new SQLiteConnection(ConnectionString))
{
c.Execute(@"drop table if exists entity");
c.Execute(@"create table entity (id integer primary key autoincrement, content varchar(100))");
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.