シングルトンパターンを実装するクラスがあり、、、、およびの3つのSQLiteOpenHelper
メソッドがあります。7つのスレッド(特定のスケジュールでトリガーされる)がデータベースにアクセスします。そのうちの6つはを使用するだけで、もう1つはデータベースが終了する前に使用して呼び出します。addLogs()
getLogs()
deleteLogs()
BroadcastReceiver
addLogs()
getLogs()
deleteLogs()
私の問題は、最後のスレッドがSQLiteデータベースに対して2つの異なる呼び出しを行うため、他のスレッドが呼び出されるaddLogs()
前でも呼び出すことができdeleteLogs()
、出力が破損することです。SQLiteOpenHelper
1つのスレッドで、への2つの呼び出しを単一のアトミックトランザクションとして処理するにはどうすればよいですか?
私が試したこと:で静的ReentrantLock
メンバーを作成し、トランザクションの前後に7つのスレッドのすべてから呼び出しSQLiteOpenHelper
ます。他の6つのスレッドは、最後のスレッドがまだロックを持っていても通過します。ロックは前に呼び出し、後に解放します。lock()
unlock()
getLogs()
deleteLogs()
更新:これは、2つのメソッドにアクセスする7番目のスレッドです。
public class Uploader extends Thread {
private Context context;
public Uploader(Context context) {
this.context = context;
}
@Override
public void run() {
Logger.d("STARTED: Uploader");
DB db = DB.getInstance(context);
List<JsonLog> logs = db.getLogs(); // FIRST CALL
String json = new Gson().toJson(logs); // convert to JSON
// connect to the server and upload
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(This.URL);
post.setHeader("content-type", "application/json");
try {
Logger.d("to upload: " + json);
StringEntity se = new StringEntity(json);
post.setEntity(se);
StatusLine status = client.execute(post).getStatusLine();
// if upload is successful
if (status.getStatusCode() == HttpStatus.SC_OK) {
db.deleteLogs(); // SECOND CALL
} else {
Logger.d("Uploader failed. " + status.getStatusCode() + ": " + status.getReasonPhrase());
}
} catch (Exception e) {
e.printStackTrace();
}
Logger.d("FINISHED: Uploader");
}
}