SQLite.NET PCL忙异常

5
我们正在Xamarin应用程序中使用SQLite.NET PCL。
在对多个表执行插入操作时,当数据库受到压力时,我们会看到抛出BUSY异常。
有人能解释一下BUSY和LOCKED之间的区别吗?是什么导致数据库处于BUSY状态?
我们的代码使用以下代码创建对数据库的单个连接:
var connectionString = new SQLiteConnectionString(GetDefaultConnectionString(), 
                                                      _databaseConfiguration.StoreTimeAsTicks);
var connectionWithLock = new SQLiteConnectionWithLock(new SQLitePlatformAndroid(), connectionString);

return new SQLiteAsyncConnection (() => { return connectionWithLock; });
3个回答

8
所以,我们的问题在于,虽然我们已经在编写的类中确保只创建一个与数据库的连接,但我们没有确保这个类是单例,因此我们仍在创建多个与数据库的连接。一旦我们确保它是一个单例,那么繁忙错误就停止了。
我从中得到的信息是:
锁定意味着您有多个线程尝试访问数据库,代码本质上不是线程安全的。
繁忙意味着您有一个线程在等待另一个线程完成,您的代码是线程安全的,但您在使用数据库时会出现争用。

你是怎么做到的 - 请给出代码示例?如果这是个愚蠢的问题,我很抱歉! - Chris M

7
当前操作无法继续进行,因为所需资源被锁定。我假设您正在使用异步插入并且处于不同的线程上,因此一个插入正在等待另一个插入的锁定完成而超时。您可以使用同步插入来避免这种情况。当需要时,我个人通过创建FIFO队列并在专用线程上同步消耗该队列来避免此情况。您还可以在让异常扩散之前重试事务X次以处理此情况。
SQLiteBusyException是一种特殊的异常,每当SQLite返回SQLITE_BUSY或SQLITE_IOERR_BLOCKED错误代码时,就会引发该异常。这些代码意味着当前操作无法继续进行,因为所需资源已被锁定。当通过SQLiteConnection.setBusyTimeout(long)设置超时时,SQLite将在指定的超时期间尝试获取锁定,然后返回此错误。
参考链接:http://www.sqlite.org/lockingv3.html

参考: http://sqlite.org/capi3ref.html#sqlite3_busy_timeout


0

我已经应用了以下解决方案,它在我的情况下(移动应用程序)有效。

  1. 使用sqlitepclraw.bundle_green nugget包与SqlitePCL一起使用。
  2. 尝试在整个应用程序中使用单个连接。
  3. 创建SQLiteConnection之后。

使用以下调用应用忙时超时。

var connection = new SQLiteConnection(databasePath: path);
SQLite3.BusyTimeout(connection.Handle, 5000); // 5000 millisecond.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接