我使用此类来管理与底层SQLiteDatabase的连接
public class BasicDataSource {
protected DatabaseHandler dbHelper;
protected volatile SQLiteDatabase readable_database;
protected volatile SQLiteDatabase writable_database;
protected Object read_lock = new Object();
protected Object write_lock = new Object();
protected Context context;
protected BasicDataSource(Context ctx) {
dbHelper = DatabaseHandler.getInstance(ctx);
getReadableDatabase();
dbHelper.onCreate(getWritableDatabase());
this.context = ctx;
}
public synchronized void close() {
dbHelper.close();
}
protected void closeInsertHelpers(InsertHelper... helpers) {
for (InsertHelper ih : helpers) {
if (ih != null)
ih.close();
}
}
protected SQLiteDatabase getReadableDatabase() {
synchronized (read_lock) {
if (readable_database == null …Run Code Online (Sandbox Code Playgroud) 我想从2个不同的线程访问SQLite数据库,从而使用2个不同的数据库连接.两个线程主要执行来自DB的读取,并且仅偶尔写入DB.如果我觉得两个线程同时写入数据库的可能性很大,我是否应该感到安全,在这种情况下我不应该有任何问题?
这个标题可能听起来有点疯狂,但这让我感到困惑.我的app大量使用本地数据库操作.正如Android文档和一些博客中所建议的那样,我扩展了SQLiteOpenHelper类并在那里定义了所有数据库操作.由于我的一些数据库操作在线程中执行,因此打开和关闭数据库会导致一些操作IllegalStateExceptions.所以,我做我的助手DB作为Singleton它解决了这些问题,也摆脱的open和close运营的每一个DB行动.现在一切似乎工作正常,即使我从未关闭数据库.
onDestroy主要活动还是其他地方?我需要从数据库中读取一些数据,同时我正在使用事务在另一个线程中加载一些数据.
读取其他表的所有线程都将停止,直到其他线程中的事务完成为止.
我需要能够从数据库中读取信息而不必担心其他线程.
我已经阅读了很多关于sqlite,android的信息...但没有任何工作,总是我的查询参数被阻止.
我遵循这个建议,因为@KevinGalligan在这个帖子中说(Android上SQLite的最佳做法是什么?)解决锁和其他问题.
1)我只使用一个SQLiteOpenHelper(单例)
2)我从未关闭数据库
我试过了:
用以下内容开始交易:
database.execSQL("begin immediate transaction");
Run Code Online (Sandbox Code Playgroud)
要么
database.beginTransactionNonExclusive();
Run Code Online (Sandbox Code Playgroud)
代替
database.beginTransaction();
Run Code Online (Sandbox Code Playgroud)
不工作,查询被阻止.
我已经读过WAL(database.enableWriteAheadLogging()),但我需要支持api 9.
同时读取事务的任何其他解决方案是更新某些表吗?我不在乎我的信息是否被弃用,更重要的是不要阻止我的线程.
我正在尝试使用Flutter的SQFlite 插件了解数据库操作。在使用推荐文档中,作者说:
该 API 很大程度上受 Android ContentProvider 的启发,其中典型的 SQLite 实现意味着在第一个请求时打开数据库并保持打开状态。
我个人在 Flutter 应用程序中有一个全局参考数据库,以避免锁定问题。如果多次调用,打开数据库应该是安全的。
如果引用丢失(并且数据库尚未关闭),仅在小部件中保留引用可能会导致热重载问题。
这是否意味着我创建了一个打开数据库连接的单例类(如这里),然后我从不关闭它?也就是说,我从不这样做:
await database.close();
Run Code Online (Sandbox Code Playgroud)
我碰到使用Android的SQLite过去的并发问题(如描述在这里),所以我通常使用的内容提供商要解决这个问题。然而,我只是在使用它,并没有真正了解内容提供商在幕后做了什么。保持与数据库的单个连接是否会做同样的事情?应用程序退出时是否需要关闭数据库?这位用户似乎认为无所谓。
我想在android中有一个连接池,因为并行线程必须同时访问数据库。
Android提供了PooledConnection与javax.sql连接一起使用的接口。由于Android中不正式支持SQLite的jdbc,因此我想到了另一种方法来实现SQLite数据库的连接池。
您如何看待这种方法。有什么风险?我有事吗
我的代码如下:
数据库的连接包装器类:
public class PoolConnection {
protected SQLiteDatabase sqlDb;
protected long openedAt;
private static final String DB_NAME = Environment
.getExternalStorageDirectory()
+ "/data/DBNAME.sqlite";
private static final int DB_VERSION = 1;
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// nothing to do here
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// no upgrade planned yet
}
}
public PoolConnection(Context …Run Code Online (Sandbox Code Playgroud) 这可能有点厚脸皮但我想要一些建议.我是Android新手,已经开始创建我的第一个应用程序.我来到我需要创建一个包含多个表的SQLite数据库的部分,并且一直在寻找最佳实践,但一直无法找到我的答案,这有点帮助但不是很多SQLite的最佳实践是什么Android的?.我总共需要6张桌子.
我应该使用一个"常量"类来保存我的所有表名,字段名和数据库名吗?
我应该创建一个"DBHelper"类来运行我的所有SQL SELECT,UPDATE,DELETE或每个表创建一个?
关于维护数据或我需要的任何其他类的最佳实践的任何其他建议?
奖金问题:)如果任何人有任何好的例子他们可以指向我,因为Android文档示例不够深入.
值得赞赏的是,我正在考虑创建一个博客,上面有一些简单的例子供新手使用,因为我读到的一些内容对于像我这样的小脑子来说有点复杂.
在onCreate()我的主要活动的方法中,我调用我的dbManager的构造函数,我调用open函数创建一个a的实例,SQLiteOpenHelper而不是我调用getWritableDatabase()它.在UIThread中,我将记录添加到数据库并将这些记录保存到ArrayList.另外两个线程检查ArrayList做什么,然后更新列表和数据库.现在我想在UI中添加一个按钮来删除数据库和列表记录AsyncTask.我已经读过该SqliteOpenHelper对象保存在一个数据库连接上.因此,如果有一个帮助程序实例,则只有一个数据库连接.此连接可以在多个线程中使用,SqliteDatabase对象使用java锁来保持访问序列化.那么如果我在数据库上写了多个线程,那么一个线程会等到前一个线程完成其操作?
添加新功能(全部删除)可能会产生问题,因为我必须避免两个线程中的一个尝试编辑不再存在的记录.我怎样才能实现目标?谢谢.
我们正在使用Xamarin用SQLite为Android和ios编写C#代码.但是关于如何使用sqlite,我似乎有一个概念上的误解:
根据stackoverflow的回答,它说 - 一个帮助器和一个数据库连接.在它周围使用锁定以确保任何时候只有一个线程正在访问sqlite db.
我的问题是 - 如果是这样的话 - 异步的用途是什么?
我试图使用同步代码的异步 - 代码给了我正确的编译错误,以避免死锁.
为什么我不能在lock语句的主体中使用'await'运算符?
public async Task InsertAsync<T> (T item){
lock (mutex) {
await asyncConnection.InsertAsync (item);
}
}
public async Task InsertOrUpdateAsync<T> (T item){
lock (mutex) {
int count = await asyncConnection.UpdateAsync (item);
if (0 == count) {
await asyncConnection.InsertAsync (item);
}
}
}
Run Code Online (Sandbox Code Playgroud)
失败.但是 - 如果我要使用锁来确保我一次使用一个连接一个线程作为sqlite中的最佳实践 - 为什么有一个异步sqlite库呢?
为什么有些线程会在网络上推广异步sqlite用法.
在android和iphone中sqlite真正的最佳实践是什么?只是使用同步版本?
我对访问SQLiteDatabase. 它应该是一个连接或多个连接才能从多个线程访问。我已经阅读了很多文章,包括以下两篇。
/sf/answers/258291841/ http://touchlabblog.tumblr.com/post/24474398246/android-sqlite-locking
这两者都建议使用单一连接。甚至我自己对同一问题的回答也被 OP 接受了。我使用了Singleton访问SQLiteopenHelper类的方法。
但是在阅读了enableWriteAheadLogging哪些州的文档后我仍然感到困惑
此方法支持从同一数据库上的多个线程并行执行查询。它通过打开到数据库的多个连接并为每个查询使用不同的数据库连接来实现这一点。数据库日志模式也更改为允许写入与读取同时进行。
现在这是令人困惑的部分。如果我想从多个线程同时访问数据库,我可以Singleton访问SQLiteOpenHelper它,在我的理解中这意味着插入的串行执行,同时同步读取可以无错误地完成。但是上面的文档说,为了同时访问,enableWriteAheadLogging应该调用它返回创建多个连接。这是怎么回事??如果我getWritableDatabase()通过Singleton SQLiteOpenHelper从多个线程调用using来进行插入,这意味着什么?电话会是连续的吗?应该enableWriteAheadLogging叫?
请说清楚。
sqlite multithreading android sqliteopenhelper android-sqlite