首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用服务和单例SQliteOpenHelper进行数据隔离

使用服务和单例SQliteOpenHelper进行数据隔离
EN

Stack Overflow用户
提问于 2014-11-04 09:05:47
回答 1查看 286关注 0票数 2

我已经用单例模式实现了SQliteOpenHelper,到目前为止它运行得很好。但请考虑以下顺序:

  • 片段启动事务以更新记录。
  • 将触发读取更新数据的服务。
  • 事务因某种原因失败,并被回滚。

该服务将处理稍后回滚的未提交数据。因此,单例模式加上服务似乎会导致数据隔离问题。然而,我读过许多建议单身人士的帖子。在使用单例时,如何处理此场景?

代码语言:javascript
复制
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;
    }
    ...
    ...
}

事务的使用:

代码语言:javascript
复制
SQLiteDatabase db = LocalDBHelper.getInstance().getWritableDatabase();
db.beginTransaction();
try{
....
...
db.setTransactionSuccessful();
}catch(Exception e){
    e.printStackTrace();
}
finally{
    db.endTransaction();
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-11-04 12:48:44

  1. 服务在主线程上运行。它没有自己的线。只有在主线程完成它的工作之后,它才会执行。因此,当事务在活动/片段中运行时,不存在服务风险。
  2. 两个线程不能访问同一个SQliteDatabase连接。该系统设计为允许每个线程访问池中的唯一连接。如果没有可用的连接,则另一个线程将等待一个连接。如果它必须等待足够长的时间,你会看到一个类似我在手机下面看到的逻辑警告。因此,单例模式补充了SQLite的线程安全。 W/SQLiteConnectionPool(12695): The connection pool for database 'xyz' has been unable to grant a connection to thread 6386 (AsyncTask #2) with flags 0x1 for 4.0 seconds. W/SQLiteConnectionPool(12695): Connections: 0 active, 1 idle, 0 available.
  3. 作为#2的结果,如果使用单例,则不可能通过另一个线程读取未提交的数据。即使不使用单例,SQLite在默认情况下也提供连接之间的数据隔离。见https://www.sqlite.org/isolation.html

结论:使用单例读取未提交数据的唯一方法是,如果您在同一个线程上,并且在事务结束之前。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26731217

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档