在我们的Android和iOS MVVMCross应用程序中,我们偶尔会遇到SQLiteException:繁忙的异常。
给定下面的代码,我们有几个存储库,每个存储库都构造了下面的实例以及与Sqlite数据库的关联连接。假设我们有一个Stocks存储库和一个Valuations存储库,将创建两个SqliteDataService实例:类型为Stocks的SqliteDataService和类型为Valuations的SqliteDataService,它们每个都与Sqlite数据库建立连接。
对存储库的操作可能在后台线程上进行,这意味着我们可能会尝试在“估值”的同时将“库存”插入数据库。
现在,假设每个存储库都创建了自己的SqliteDataService,则connectionObject锁将仅保护相同的存储库类型以防止同时访问数据库,而不是保护Stocks和Valuations防止同时访问数据库。
我的问题是:
在每个存储库中创建连接是否有效?如果是,我们如何防范SqliteException:繁忙?
有没有更好的模式?即我们是否应该创建一个非通用的SqliteDataService类,该类在线程之间共享相同的连接?我们已经尝试过了,但是在Android上我们会遇到致命的异常。
是否有人对Xamarin MVVMCross有可靠的Sqlite DAL模式?
public class SqliteDataService<T> : IDataService<T> where T : new()
{
private static object lockObject = new object();
private static object connectionObject = new object();
private static ISQLiteConnection _connection;
private static SqliteDataService<T> _instance;
public SqliteDataService(ISQLiteConnectionFactory connectionFactory, string dbPath)
{
if (_connection == null)
{
_connection = connectionFactory.Create (dbPath);
_connection.CreateTable<T> ();
}
}
public static SqliteDataService<T> GetInstance(ISQLiteConnectionFactory connectionFactory, string dbPath)
{
if (_instance == null)
{
lock (lockObject)
{
_instance = new SqliteDataService<T> (connectionFactory, dbPath);
}
}
return _instance;
}
public void CreateTable<T> ()
{
}
public void Insert(T value)
{
lock (connectionObject) {
_connection.Insert (value, typeof(T));
}
}
public void InsertAll(IEnumerable<T> values)
{
lock (connectionObject) {
_connection.Insert (values, typeof(T));
}
}
public IEnumerable<T> Read(Expression<Func<T, bool>> predicate)
{
lock (connectionObject) {
return _connection.Table<T> ().Where (predicate);
}
}
public T ReadFirst(Expression<Func<T, bool>> predicate)
{
lock (connectionObject) {
return Read (predicate).FirstOrDefault ();
}
}
public void Update(T value)
{
lock (connectionObject) {
_connection.Update (value, typeof(T));
}
}
public void Delete(Expression<Func<T, bool>> predicate)
{
lock (connectionObject) {
var valuesToDelete = Read (predicate);
if (valuesToDelete == null)
return;
foreach (var value in valuesToDelete) {
_connection.Delete (value);
}
}
最佳答案
听起来您有几种选择:
关于android - SqliteException繁忙的iOS/Android Xamarin MVVMCross,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29797572/