- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
在我们的 Android 和 iOS MVVMCross 应用程序中,我们偶尔会遇到 SQLiteException: busy 异常。
给定下面的代码,我们有几个存储库,每个存储库都构造一个下面的实例和一个到 Sqlite 数据库的关联连接。假设我们有一个 Stocks Repository 和一个 Valuations Repository,将创建两个 SqliteDataService 实例:类型为 Stocks 的 SqliteDataService 和类型为 Valuations 的 SqliteDataService,每个实例都与 Sqlite 数据库连接。
存储库上的操作可能在后台线程上运行,这意味着我们可能会尝试在估值的同时将股票插入数据库。
现在假设每个存储库都创建了自己的 SqliteDataService,connectionObject 锁只会保护相同的存储库类型免于同时访问数据库,而不是保护 Stocks 和 Valuations 免于同时访问数据库。
我的问题是:
为每个存储库创建一个连接是否有效?如果有效,我们如何防止 SqliteException: busy?
还有更好的模式吗?即我们是否应该创建一个跨线程共享相同连接的非通用 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);
}
}
最佳答案
听起来您有几个选择:
仅实例化一个 SqliteDataService 并将对它的引用传递给您的 Stocks 和 Valuations 对象,这似乎是最明智的,因为它们都在同一个数据库上运行
实例化一个对象以用作服务外部的锁,并将引用传递给 SqliteDataService 构造函数,以便两个服务共享锁。我相信这会奏效,但我不是锁定方面的专家。
您可以在 try catch block 中处理 Busy 异常,并迭代一个计数器以对数据库进行最大次数的尝试,每次等待很短,这样您就有很好的连接机会。如果数据库仍然很忙,你仍然会得到异常,这个解决方案是一个相当困惑的解决方案。
重构 DB 以便将两个区域分开,这可能是不可能的,但值得考虑。
关于android - SqliteException 忙 iOS/Android Xamarin MVVMCross,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29797572/
根据https://developers.google.com/google-apps/calendar/v3/reference/freebusy/query处的文档要执行空闲/忙碌查询,您必须在正
我在启动 Apache 后使用 XAMPP 1.7.7 我收到此警报: Busy... Apache started [Port 80] 我已经打开了 httpd.conf 文件,并将端口号更改为 8
我有端口问题。 每当我启动 Apache 时,它都会给我这个错误: Busy - Apache Started [port 80] 当我启动 Mysql 时出现以下错误: Busy - ERROR
当我运行我的代码时,我总是得到后台工作人员很忙。有帮助吗? struct FtpSetting { public string Server { get; set
在我们的 Android 和 iOS MVVMCross 应用程序中,我们偶尔会遇到 SQLiteException: busy 异常。 给定下面的代码,我们有几个存储库,每个存储库都构造一个下面的实
每次运行解决方案(20 projs)时,我都会收到此错误。我尝试禁用 UI 选项、resharper、删除未使用的扩展等,但仍然无法通过此错误。 我使用的是 VS 2015 Update 2 Ente
我正在使用这个插件 https://github.com/mozilla/rust-android-gradle ,这需要我添加 tasks.whenTaskAdded { task -> i
我是一名优秀的程序员,十分优秀!