SQLite y "Base de datos está bloqueada"

c# dapper sqlite

Pregunta

Uso de SQLite, System.Data.SQLite y Dapper (en una aplicación de consola; posterior Servicio de Windows; alto rendimiento); ¿Por qué "la base de datos está bloqueada" está allí de todos modos?

Incluso resumí todas las llamadas a SQLite db en este método:

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

Activar la opción mapeada en memoria tampoco ayudó:

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

Y esta es la cadena de conexión:

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

¿Que me estoy perdiendo aqui?

Nota: Cuando busca "la base de datos está bloqueada", todos los resultados principales (y la primera página completa) tratan sobre este problema en diferentes plataformas y lenguajes de programación. Parece que hay algo más sobre SQLite que no puedo filtrar de esta imagen.

Respuesta popular

Como mencioné en mi comentario, NO tengo idea de lo que ocurre, está pasando sin ver más de su código.

Aún así, si no está dispuesto a cambiar Dapper a Sqlite-net, a continuación se muestra un pequeño ejemplo sin bloqueos, utilizando su abstracción, que no arroja ninguna excepción. Espero que te ayude a resolverlo.

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

enter image description here



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow