You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8 Azure Functions迁移SQLite遇SQLite Error 5数据库锁定问题求助

SQLite Error 5: 'database is locked' 问题排查(Azure Functions + .NET 8 + EF Core)

我有一个基于.NET 8的Azure Functions应用,原本用SQL Server存储数据,为了提升访问速度、降低成本,正在迁移到SQLite。本地运行一切正常,但部署到Azure Functions后,执行SELECT查询时出现如下错误:

2025-06-05T16:28:16Z   [Error]   An exception occurred while iterating over the results of a query for context type 'Infrastructure.Persistence.MLTrainingContext'.
Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 5: 'database is locked'.
   at Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db)
   at Microsoft.Data.Sqlite.SqliteCommand.PrepareAndEnumerateStatements()+MoveNext()
   at Microsoft.Data.Sqlite.SqliteCommand.GetStatements()+MoveNext()
   at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
   at Microsoft.Data.Sqlite.SqliteCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.InitializeReader(Enumerator enumerator)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.<>c.<MoveNext>b__21_0(DbContext _, Enumerator enumerator)
   at Microsoft.EntityFrameworkCore.Storage.NonRetryingExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()

我确认当前只有该应用访问DbContext及数据库,且无并发函数同时访问数据库,请问问题原因是什么?

DbContext代码如下:

using Domain;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;

namespace Infrastructure.Persistence
{
    public class MLTrainingContext : DbContext
    {
        public DbSet<Model> Models { get; set; }
        public DbSet<Library> Libraries { get; set; }
        public DbSet<DestinationRoutingRule> DestinationRoutingRules { get; set; }

        private readonly string _connString;

        public MLTrainingContext(DbContextOptions<MLTrainingContext> options) : base(options)
        {
            _connString = Utils.GetDBConnectionString();
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Model>().HasMany(m => m.Libraries)
                .WithMany(l => l.Models);
        }

        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
            options.UseSqlite(_connString,
            x => x.MigrationsAssembly("Infrastructure"));

            options.ConfigureWarnings(warnings =>
                warnings.Ignore(RelationalEventId.NonTransactionalMigrationOperationWarning));
        }

        public void Save()
        {
            lock (this)
            {
                SaveChanges();
            }
        }
    }
}

问题原因分析

  • Azure Functions文件系统限制:Azure Functions默认使用的远程共享存储(如wwwroot目录),其文件锁机制与本地文件系统差异极大,SQLite对文件系统一致性要求高,共享存储的延迟或隐性操作(如系统快照、后台扫描)会干扰SQLite的文件锁逻辑,即使无业务并发也可能触发锁超时。

  • DbContext配置冲突:构造函数接收了DbContextOptions<MLTrainingContext>注入参数,但OnConfiguring又手动调用UseSqlite覆盖配置,这种双重配置会导致EF Core连接生命周期异常,可能创建多个独立连接池,引发锁冲突。

  • 锁机制无效:Save方法里的lock (this)仅对当前DbContext实例生效,若Azure Functions将DbContext配置为瞬态(Transient)或范围(Scoped),每次请求都会创建新实例,锁完全无法起到全局互斥作用,反而可能加剧多实例操作数据库的锁竞争。

  • 连接未及时释放:若查询结果未被完整枚举(如未调用ToList()就提前释放DbContext),或请求结束后DbContext未被正确Dispose,会导致SQLite连接长时间持有数据库文件锁,后续查询触发锁等待超时。


内容的提问来源于stack exchange,提问作者Justin Lyon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 22:23:21