Android 使用服务和单例SQliteOpenHelper进行数据隔离
我已经用单例模式实现了SQliteOpenHelper,到目前为止它运行良好。但是考虑下面的顺序:Android 使用服务和单例SQliteOpenHelper进行数据隔离,android,android-sqlite,Android,Android Sqlite,我已经用单例模式实现了SQliteOpenHelper,到目前为止它运行良好。但是考虑下面的顺序: 片段启动事务以更新记录 触发读取更新数据的服务 事务因某种原因失败并被回滚 服务将处理稍后回滚的未提交数据。因此,单例模式与服务的耦合似乎会导致数据隔离问题。然而,我读过很多推荐单身人士的帖子。使用单例时如何处理这种情况 public class MyApplication extends Application{ private static MyApplication instan
- 片段启动事务以更新记录
- 触发读取更新数据的服务
- 事务因某种原因失败并被回滚
public class MyApplication extends Application{
private static MyApplication instance;
public MyApplication(){
instance = this;
}
public static Context getContext(){
return instance;
}
}
public class LocalDBHelper extends SQLiteOpenHelper{
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "MyDB";
private static final String LOG_TAG = "LocalDBHelper";
private static LocalDBHelper instance = null;
/*private constructor to avoid direct instantiation by other classes*/
private LocalDBHelper(){
super(MyApplication.getContext(), DATABASE_NAME, null, DATABASE_VERSION);
}
/*synchronized method to ensure only 1 instance of LocalDBHelper exists*/
public static synchronized LocalDBHelper getInstance(){
if(instance == null){
instance = new LocalDBHelper();
}
return instance;
}
...
...
}
与事务一起使用:
SQLiteDatabase db = LocalDBHelper.getInstance().getWritableDatabase();
db.beginTransaction();
try{
....
...
db.setTransactionSuccessful();
}catch(Exception e){
e.printStackTrace();
}
finally{
db.endTransaction();
}
SQliteDatabase
连接。系统设计为允许每个线程访问池中的唯一连接。如果没有可用的连接,其他线程将等待一个。如果它必须等待足够长的时间,你会看到一个类似于我在手机下面看到的logcat警告。因此,单例模式补充了SQLite的线程安全性
W/SQLiteConnectionPool(12695):数据库“xyz”的连接池在4.0秒内无法授予与带有标志0x1的线程6386(AsyncTask#2)的连接。
W/SQLiteConnectionPool(12695):连接:0个活动,1个空闲,0个可用。
结论:使用单例读取未提交数据的唯一方法是,如果您在同一线程上,并且在事务结束之前。您应该检查以下内容:@user2247689谢谢我在3个不同的站点上读过同一篇文章:),但它不处理事务或隔离,这与问题无关。对不起,我没有正确阅读问题。处理服务有点棘手,尤其是当它们必须并发时。基本上我猜你必须使用“消息”吗?请参见此
SQLiteDatabase
维护由线程本地数据库会话获取的活动连接池`-多个线程永远无法获取相同的连接。@corsair992!您完全正确请注意,如果未启用预写日志记录,则连接池当前设置为最大值1,但这实际上不是必需的,将来可能会更改。但是,每个线程将使用不同的会话,并从池中获取唯一的连接。SQLite当然仍然会实现自己的锁定和并发模型。谢谢@corsair992。我混淆了SQLiteDatabase实例和连接实例。我编辑了#2以反映您的评论。