这就是我的问题:
我有一个包含列的表:ID,VALUE和SYNCHRONICED。最后一个标志指示自上次更新以来是否已将一行发送到服务器。我有一些可以访问数据库的线程
我的问题出现在那个用例中(有两个线程T1和T2:
T1-->Start_Send-->Query_Values-->Send_to_server-->wait_answer-->sync=1_for_sent_rows
T2------------------------->Update_a_row_sent
此时T1标记为sync = 1,由T2更新的值。
有没有办法避免这个问题?
由于
答案 0 :(得分:8)
由于您询问了如何在android上锁定数据库/表,您可以使用SQLiteDatabase.beginTransaction()来实现:
来自android docs http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html:
public void beginTransaction()
自:API Level 1
在EXCLUSIVE模式下开始交易。
来自sqlite 3 http://www.sqlite.org/lang_transaction.html
在BEGIN EXCLUSIVE之后,除了之外没有其他数据库连接 read_uncommitted连接将能够读取数据库而不是 其他连接无一例外都能编写数据库 直到交易完成。
beginTransaction启动事务并将数据库置于独占锁定状态,因此当T1 select运行时,它会阻止T2更新行,直到T1调用db.endTransaction()。
public yourMethod() {
db.beginTransaction();
//do whatever you want with db;
db.setTransactionSuccessful();
db.endTransaction();
}
答案 1 :(得分:2)
假设插入或更新记录时SYNCHRONICED
为0,将记录发送到服务器时为1,服务器确认同步时为2。
T1线程应该:
BEGIN;
SELECT ID, VALUE FROM TAB WHERE SYNCHRONICED = 0;
UPDATE TAB SET SYNCHRONICED = 1 WHERE SYNCHRONICED = 0;
COMMIT;
select
语句将记录发送到服务器。
现在任何insert
或update
到TAB应设置SYNCHRONICED = 0;
当服务器用ack响应时,
UPDATE TAB SET SYNCHRONICED = 2 WHERE SYNCHRONICED = 1;
这不会影响因SYNCHRONICED
为0而更新或插入的任何记录。