首页 > 解决方案 > SQLite 抛出繁忙异常并被锁定

问题描述

我有一个用xamarin. 这是崩溃的代码,不是第一次,而是第二次!

        public void InsertOrUpdateInventoryWithoutEntries(Inventory inventory)
        {
        _logger.Debug("Enter");
        try
        {
            var db = _dataBaseConnection.GetSqLiteConnection();
            using (db)
            {
                var existingDbInventory = db.Find<DbInventory>(dbInventory => dbInventory.Code == 
                 inventory.Code);
                if (existingDbInventory != null)
                {
                    if (!existingDbInventory.Finished ) // do not update if finished.
                    {
                        existingDbInventory.Description = inventory.Description;

                        existingDbInventory.OpenTime = inventory.OpenTime;
                        existingDbInventory.Finished = inventory.Finished ;
                        existingDbInventory.UseInventoryList = inventory.UseInventoryList;
                        existingDbInventory.PostedToServer = inventory.PostedToServer;
                        existingDbInventory.InventoryListIsDownloaded = 
                                                      inventory.InventoryListIsDownloaded;
                        UpdateInventory(existingDbInventory,db);

                    }
                }
                else
                {
                    db.Insert(DbInventory.FromInventory(inventory));
                }
                db.Close();
            }
        }
        catch
        (SQLiteException ex)
        {
            _logger.Error(ex);
            throw;
        }
    }

        private void UpdateInventory(DbInventory inventory, SQLiteConnection db)
    {
        _logger.Debug("Enter");
        try
        {
           var result = db.Update(inventory);

        }
        catch (SQLiteException ex)
        {
            _logger.Error(ex);
            throw;
        }
    }
        public bool InsertOrUpdateInventoryEntry(InventoryEntry inventoryEntryModel, 
        SQLiteConnection db=null)
    {
        _logger.Debug("Enter");
        bool disposeFlg = false;

        //detta då sqllite inte klarar av samtidiga anrop så bra, så man skall bara använda en 
         connection i taget !
        if (db == null)
        {
            db = _dataBaseConnection.GetSqLiteConnection();
            disposeFlg = true;
        }

        var existingDbInvetoryRow = db.Find<DbInventoryEntry>(dbInventoryRow => 
             dbInventoryRow.ItemId == inventoryEntryModel.ItemId && dbInventoryRow.InventoryCode == 

            inventoryEntryModel.InventoryCode);
            if (existingDbInvetoryRow != null)
            {
                existingDbInvetoryRow.Cost = inventoryEntryModel.Cost;
                existingDbInvetoryRow.Quantity = inventoryEntryModel.Quantity;

                db.Update(existingDbInvetoryRow);
            }
            else
            {
                db.Insert(DbInventoryEntry.FromInventoryEntry(inventoryEntryModel));
            }

            if (disposeFlg)
            {
                db.Close();
                db.Dispose();
            }

            return true;
    }
       private bool InsertInventoryRows(IEnumerable<InventoryEntry> inventoryEntryModels)
    {
        _logger.Debug("Enter");
        var dbRows = inventoryEntryModels.Select(entry => 
        (DbInventoryEntry.FromInventoryEntry(entry)));

        var db = _dataBaseConnection.GetSqLiteConnection();

        using (db)
        {
            db.InsertAll(dbRows);

            db.Close();
        }
        return true;
    }

我得到的错误是:

SQLite.SQLiteException: '数据库已锁定' 或 SQLite.SQLiteException: '数据库正忙'

标签: c#sqlitexamarin

解决方案


感谢 Jason,我找到了解决方案 - github.com/praeclarum/sqlite-net/issues/700

我建议您为您的应用程序保留一个 SQLiteConnection 并将其缓存以利用类型映射缓存策略。用 Create | 打开它 读写 | FullMutex 标志将确保所有操作都是多线程序列化的。每当您的应用关闭时,不要忘记 Dispose 连接

这完美地工作并加速了应用程序!谢谢杰森!

我所做的是处理一个我一直保持打开状态的静态连接


推荐阅读