SQLite et "Database est verrouillée"

c# dapper sqlite

Question

Utilisation de SQLite, System.Data.SQLite et Dapper (dans une application console; service Windows ultérieur; haut débit); pourquoi "la base de données est verrouillée" existe-t-il de toute façon?

J'ai même résumé tous les appels à SQLite db dans cette méthode:

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

Activer l'option mappée en mémoire n'a pas aidé non plus:

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

Et ceci est la chaîne de connexion:

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

Qu'est-ce que j'oublie ici?

Remarque: Lorsque vous recherchez Google pour "base de données verrouillée", tous les principaux résultats (et toute la première page) concernent ce problème dans différents langages de programmation et plates-formes. Il semble qu'il y ait quelque chose d'autre à propos de SQLite que je ne peux pas filtrer de cette image.

Réponse populaire

Comme indiqué dans mon commentaire, je n'ai aucune idée de quoi que ce soit, se passe sans voir plus de votre code.

Cependant, si vous ne souhaitez pas changer Dapper en Sqlite-net, voici un petit exemple non bloquant, utilisant votre abstraction, qui ne génère aucune exception. J'espère que cela vous aidera à comprendre.

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

entrer la description de l'image ici



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow