SQLite und "Datenbank ist gesperrt"

c# dapper sqlite

Frage

Verwenden von SQLite, System.Data.SQLite und Dapper (in einer Konsolenanwendung; später Windows-Dienst; hoher Durchsatz); Warum ist "Datenbank gesperrt" überhaupt vorhanden?

Ich habe sogar alle Aufrufe an SQLite db in dieser Methode abstrahiert:

public static void LocalDbScope(Action<IDbConnection> action)
{
    try
    {
        lock (DbLock)
        {
            using (var connection = Open(LocalStorageConnectionString))
            {
                action(connection);
            }
        }
    }
    catch (Exception xux)
    {
        ErrLog.Error(xux);
        throw;
    }
}

Das Aktivieren der speicherplatzierten Option hat auch nicht geholfen:

connection.Execute("PRAGMA wal_autocheckpoint=32; PRAGMA journal_size_limit = 2048;");
connection.Execute("PRAGMA mmap_size=" + GB);

Und das ist Verbindungszeichenfolge:

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();

Was fehlt mir hier?

Hinweis: Wenn Sie nach "Datenbank ist gesperrt" suchen, handelt es sich bei allen Top-Ergebnissen (und der gesamten ersten Seite) um dieses Problem in verschiedenen Programmiersprachen und Plattformen. Anscheinend gibt es etwas anderes über SQLite, das ich nicht aus diesem Bild herausfiltern kann.

Beliebte Antwort

Wie in meinem Kommentar erwähnt, habe ich keine Ahnung, was auch immer passiert, ohne mehr von Ihrem Code zu sehen.

Wenn Sie Dapper nicht zu Sqlite-net wechseln wollen, ist unten ein kleines nicht blockierendes Beispiel, das Ihre Abstraktion verwendet, die keine Ausnahmen verursacht. Hoffe es hilft dir, es herauszufinden.

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))");
            }
        }
    }
}

Bildbeschreibung hier eingeben



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow