SQLite 및 "데이터베이스 잠김"

c# dapper sqlite

문제

SQLite, System.Data.SQLite 및 Dapper 사용 (콘솔 응용 프로그램에서, 이후 Windows 서비스, 높은 처리량); 왜 "데이터베이스가 잠겨있습니까?"어쨌든 거기에 있습니까?

나는이 메서드에서 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 with attribution
와 제휴하지 않음 Stack Overflow
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow