在sqlite中锁定数据库或表(Android)

时间:2011-08-03 23:34:05

标签: android sql sqlite thread-safety

这就是我的问题:

我有一个包含列的表: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更新的值。

有没有办法避免这个问题?

  • 查询和更新的方法不同,因此无法在方法中使用synchronized。
  • 如果T2在T1结束前被阻止,则没有问题

由于

2 个答案:

答案 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语句将记录发送到服务器。

现在任何insertupdate到TAB应设置SYNCHRONICED = 0;

当服务器用ack响应时,

UPDATE TAB SET SYNCHRONICED = 2 WHERE SYNCHRONICED = 1;

这不会影响因SYNCHRONICED为0而更新或插入的任何记录。