2014-11-04 4 views
1

Я реализовал SQliteOpenHelper с шаблоном Singleton и работает до сих пор. Но рассмотрим ниже последовательности:данные Изоляция с сервисами и Singleton SQliteOpenHelper

  • фрагмент запускает транзакцию обновления записей
  • Служба получает срабатывает, который считывает обновленные данные
  • сделка терпит неудачу по какой-то причине и откатывается

Служба обработала бы незафиксированные данные, которые позже были отброшены. Таким образом, кажется, что одноэлементный шаблон в сочетании с сервисом вызывает проблемы с изоляцией данных. Тем не менее, я прочитал множество сообщений, рекомендующих синглтон. Как обрабатывать этот сценарий при использовании одноэлементного?

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(); 
} 
+0

вы должны проверить это: http://blog.lemberg.co.uk/concurrent-database-access –

+0

@ user2247689 спасибо, что я прочитал эту же статью на трех разных сайтах :) Но это не касается транзакций или изоляции, так что это не имеет отношения к вопросу. – faizal

+0

Извините, я не правильно прочитал вопрос. Работа с сервисами очень сложна, особенно когда они должны быть параллельными. В принципе, я думаю, вам придется использовать «Сообщения»? см. это http://developer.android.com/guide/components/bound-services.html#Messenger –

ответ

2
  1. Служба работает в основном потоке. У него нет собственной нити. Он будет выполняться только после того, как основной поток завершит работу. Таким образом, нет риска для службы, начиная с транзакции в действии/фрагменте.

  2. Два потока не могут получить доступ к тому же SQliteDatabase. Система предназначена для обеспечения доступа каждого потока к уникальному соединению из пула. Если соединений нет, другой поток (ы) будет ждать один. Если вам нужно подождать достаточно долго, вы увидите предупреждение logcat, подобное тому, что я вижу на своем телефоне ниже. Таким образом, шаблон singleton дополняет безопасность потока 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.

Вывод: Единственный способ читать неподтвержденные данные с одноточечного, если вы находитесь на том же потоке, и перед сделка закончилась.

+1

Обратите внимание, что хотя пул соединений в настоящее время установлен на максимум один, если запись на запись не включена, это на самом деле не требуется и может быть изменено в будущем. Однако каждый поток будет использовать другой сеанс и получить уникальное соединение из пула. Разумеется, SQLite по-прежнему будет реализовывать собственную модель блокировки и параллелизма. – corsair992

+0

спасибо @ corsair992.Я смутил экземпляр SQLiteDatabase экземпляром подключения. Я отредактировал # 2, чтобы отразить ваш комментарий. – faizal

Смежные вопросы