2016-09-19 100 views
4

我们在Xamarin应用程序中使用SQLite.NET PCL。SQLite.NET PCL繁忙异常

当通过插入多个表使数据库处于压力下时,我们看到抛出了BUSY异常。

任何人都可以解释什么是BUSY和LOCKED之间的区别?什么导致数据库繁忙?

我们的代码使用使用下面的代码创建的数据库的单个连接:

var connectionString = new SQLiteConnectionString(GetDefaultConnectionString(), 
                 _databaseConfiguration.StoreTimeAsTicks); 
var connectionWithLock = new SQLiteConnectionWithLock(new SQLitePlatformAndroid(), connectionString); 

return new SQLiteAsyncConnection (() => { return connectionWithLock; }); 

回答

2

所以我们的问题竟然是,虽然我们已经在类中保证,我们会写,它只是创建到数据库的连接我们并没有确保这个类是单例,因此我们仍然创建了多个到数据库的连接。一旦我们保证这是一个单身那么忙错误停止

我所采取的是这样的:

锁定意味着你有多个线程试图访问数据库,代码本身不是线程安全的。

忙意味着你有一个线程在另一个线程上等待完成,你的代码是线程安全的,但你在使用数据库时看到了争用。

1

...当前操作无法继续,因为所需要的资源锁定 ...

我是假设您正在使用async -style inserts并且在不同的线程上d因此插件正在等待不同插件的锁定完成。您可以使用同步插入来避免这种情况。我个人在需要时通过创建一个FIFO队列并在专用线程上同步使用该队列来避免这种情况。您也可以在让Exception波动起来之前重试您的交易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