2017-06-23 18 views
8

Với cơ sở dữ liệu Phòng mới trong Android, tôi có một yêu cầu nơi có hai cuộc phẫu thuật liên tiếp mà cần phải được thực hiện:Phòng Android cơ sở dữ liệu giao dịch

removeRows(ids); 
insertRows(ids); 

Nếu tôi chạy này, tôi thấy (trên kiểm tra db) có một số hàng bị thiếu - tôi cho rằng chúng đang bị xóa sau khi chèn. viz. hoạt động đầu tiên chạy song song với lần thứ hai.

Nếu tôi sử dụng một khối giao dịch, như thế này, thì đó là tất cả tiền phạt - hoạt động đầu tiên dường như để hoàn thành trước khi thực hiện thứ hai:

roomDb.beginTransaction(); 
removeRows(ids); 
roomDb.endTransaction(); 

insertRows(ids); 

Nó cũng tốt nếu tôi cung cấp cho một giấc ngủ ở giữa thay vì :

removeRows(ids); 
Thread.sleep(500); 

insertRows(ids); 

Hiện không có vẻ được nhiều tài liệu cho phòng, và đã tự hỏi nếu tôi nên sử dụng các khối giao dịch như trên khi tôi có hoạt động liên tục được thực hiện, hoặc là có cách nào tốt hơn để làm nó.

EDIT: Sau @CommonsWare chỉ ra, @Query là không đồng bộ, trong khi @Insert@Delete là đồng bộ. Trong quan điểm này, làm thế nào tôi sẽ nhận được một truy vấn mà xóa hàng để được async:

@Query("DELETE from table WHERE id IN(:ids)") 
int removeRows(List<Long> ids); 

Theo build ra tôi nhận được Deletion methods must either return void or return int (the number of deleted rows), nếu tôi cố gắng quấn kiểu trả về trong một Flowable.

+1

gì chính xác là những hiện thực của 'removeRows()' và 'insertRows()'? Nếu chúng là các phương thức '@ Delete' và' @ Insert' DAO đơn giản, thì chúng nên được tuần tự hóa một cách tự nhiên, vì các phương thức đó được thực thi đồng bộ. Nơi duy nhất mà Room thực hiện công cụ không đồng bộ là trên '@ Query' với giá trị trả về (' LiveData', 'Flowable', v.v.). – CommonsWare

+0

@CommonsWare, vâng, trong khi 'insertRows()' là '@ Insert' đơn giản,' removeRows() 'có các cuộc gọi' @ Query'. Tôi đoán điều đó giải thích nó. Vì vậy, tôi đoán câu trả lời cho câu hỏi của tôi là đăng ký phản ứng phản ứng của các truy vấn. – rajath

+0

@CommonsWare, Cảm ơn sự giúp đỡ của bạn. Tôi đã chỉnh sửa câu hỏi theo dõi dựa trên nhận xét của bạn. Làm thế nào tôi có thể viết một '@ Query' có một' DELETE' để nó có thể quan sát nó cho đến khi hoàn thành? – rajath

Trả lời

5

Như @CommonsWare đã chỉ ra, @Query không đồng bộ, trong khi @Insert, @Delete, @Update là đồng bộ.

Nếu bạn muốn thực hiện nhiều truy vấn trong một giao dịch, Room cũng cung cấp một phương thức cho điều đó như được đề cập bên dưới.

roomDB.runInTransaction(new Runnable() { 
     @Override 
     public void run() { 
      removeRows(ids); 
      insertRows(ids); 
     } 
    }); 

Tôi hy vọng điều này sẽ giải quyết được vấn đề của bạn.

5

như chỉ ra trên tài liệu cho Transaction, bạn có thể làm như sau:

@Dao 
public abstract class ProductDao { 
    @Insert 
    public abstract void insert(Product product); 

    @Delete 
    public abstract void delete(Product product); 

    @Transaction 
    public void insertAndDeleteInTransaction(Product newProduct, Product oldProduct) { 
     // Anything inside this method runs in a single transaction. 
     insert(newProduct); 
     delete(oldProduct); 
    } 
} 
+0

nếu tôi đang sử dụng giao diện thì sao? –

+2

@johnny_crq Tôi đã sử dụng giao diện và không khó để chuyển sang lớp trừu tượng. cách khác bạn có thể thử thủ thuật xấu xí này trên giao diện '@Transaction @Query (" DELETE FROM products; INSERT INTO giá trị sản phẩm (x, y, z) ")' trên phương thức. – guness

Các vấn đề liên quan