我有一个SQLiteOpenHelper
实现单例模式的类,并具有三种方法:addLogs()
、getLogs()
和deleteLogs()
。BroadcastReceiver
七个线程(由 a在某些时间表触发)访问数据库——其中六个仅使用addLogs()
,另一个在完成之前使用getLogs()
和调用。deleteLogs()
我的问题是,因为最后一个线程对 SQLite 数据库进行了两次不同的调用,所以其他线程addLogs()
甚至可以在调用之前deleteLogs()
调用,这会破坏我的输出。如何使一个线程将两个调用SQLiteOpenHelper
视为单个原子事务?
我尝试过的:在 , 中创建一个静态ReentrantLock
成员,并在事务之前和之后从七个线程中的每一个SQLiteOpenHelper
调用lock()
and 。unlock()
即使最后一个线程仍然有锁,其他六个线程仍然可以通过,它在之前调用getLogs()
并在之后释放deleteLogs()
。
更新:这是访问这两种方法的第七个线程。
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");
}
}