c# - 数据库已锁定:在我的 android 和 ios xamarin 应用程序上引发 SQLite 异常
问题描述
数据库非常稳定,直到我完成所有包和捆绑签名并将应用程序部署到应用程序中心进行分布式测试,然后我开始从 SQLite 数据库中收到各种错误。我做了一些研究,知道数据库不是线程安全的,但是我怎样才能使它成为线程安全的,我所有的数据库连接和查询都是通过异步的。
这是我的数据库连接
private static object collisionLock = new object();
//local SQLite database.
public SQLiteAsyncConnection Db;
private Uri url;
private MemberDataStore membersStore;
private AdvantageMemberDataStore advMembersStore;
private EventDataStore eventDataStore;
public ConnectionsUtil()
{
Db = DependencyService.Get<IDatabaseConnection>().DbConnection();
}
这是执行插入和更新的代码,我有三种方法,如下面的一种访问数据库和许多在应用程序中使用 Db 的查询
public async Task GetAdvantageMembersAsync(AdvantageMemberDataStore store)
{
await Db.QueryAsync<AdvantageMember>("DROP TABLE IF EXISTS AdvantageMember").ContinueWith(t =>
{
Db.CreateTableAsync<AdvantageMember>();
Console.WriteLine("AdvantageMember table created!");
});
url = new Uri("http://54.39.180.209/benefits");
Console.WriteLine("Gideon: Attempting to get advantage members.");
try
{
string json;
//Gideon: get json string containing advantage members.
using (WebClient sr = new WebClient())
{
Console.WriteLine("Gideon: Retrieving advantage Members....");
sr.DownloadStringCompleted += async (s, e) =>
{
Console.WriteLine("Gideon: Advantage Members Downloaded. Processing advantage Members....");
json = e.Result;
lock (collisionLock)
{
Db.InsertAllAsync(JsonConvert.DeserializeObject<IEnumerable<AdvantageMember>>(json)).ContinueWith(async t =>
{
await store.UpdateItemsAsync(Db.QueryAsync<AdvantageMember>("SELECT * FROM AdvantageMember GROUP BY Title").Result);
});
}
Console.WriteLine("Processing Members benefits for android");
advMembersStore = store;
};
await Task.Run(() => sr.DownloadStringAsync(url));
}
}
catch (Exception e)
{
Console.WriteLine("Gideon: An error occured while trying to dbect. ERROR: " + e);
}
}
**This is the code that specify the folder for the sqlite connection**
public class DatabaseConnection_iOS: Services.IDatabaseConnection
{
public SQLiteAsyncConnection DbConnection()
{
var dbName = "MyDb.db3";
string personalFolder =
Environment.
GetFolderPath(Environment.SpecialFolder.Personal);
string libraryFolder =
Path.Combine(personalFolder, "..", "Library");
var path = Path.Combine(libraryFolder, dbName);
return new SQLiteAsyncConnection(path);
}
}
解决方案
就我而言,我将 SaveContext 放在 foreach 中
var transaction = _context.Database.BeginTransaction();
try
{
foreach (var item in obj)
{
_context.EntrevistaNacionals.Add(item);
await _context.SaveChangesAsync(); //--wrong
}
transaction.Commit();
return true;
}
推荐阅读
- ruby - 似乎无法运行 ruby 2.6.0 自制版本 - 总是引用系统 ruby 2.3.0
- c# - 将数据从模型导入视图给我一个我无法解决的错误
- reactjs - 抓取 Google 显示空白页 - Reactjs
- java - 如何等待短信发送确认,然后发送下一条短信 Android
- javascript - 在 javascript 中读取 iFrame(不在同一域 - YouTube)中的 div 状态
- git - SVN 到 Git 迁移:将选定的一组提交移动到新存储库
- python - 如何将第二轴添加到 holoviews 的散景图中?
- python - 如何使用熊猫从字符串中删除小数点
- node.js - winston 'handleExceptions: true' 记录两次
- maven - 无法执行 SonarQube:无法从服务器获取引导索引: