首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android数据库事务

Android数据库事务
EN

Stack Overflow用户
提问于 2017-06-23 02:00:59
回答 4查看 42.6K关注 0票数 43

使用Android中的新的房间数据库,我有一个需要进行两个顺序操作的要求:

代码语言:javascript
复制
removeRows(ids);
insertRows(ids);

如果我运行这个程序,我就会发现(在检查db)中缺少了一些行--我假设它们在插入后被删除了。那就是。第一操作与第二操作并行运行。

如果我使用了一个事务块,比如这样的,那么就可以了--第一个操作在执行第二个操作之前似乎已经完成了:

代码语言:javascript
复制
roomDb.beginTransaction();
removeRows(ids);
roomDb.endTransaction();

insertRows(ids);

如果我在中间睡一觉也没关系:

代码语言:javascript
复制
removeRows(ids);
Thread.sleep(500);

insertRows(ids);

对于Room,似乎没有太多的文档,当我有顺序的操作要做时,我想知道是否应该像上面那样使用事务块,或者有更好的方法来完成它。

编辑:@CommonsWare指出后,@Query是异步的,而@Insert@Delete是同步的。有鉴于此,如何获得将行删除为异步的查询:

代码语言:javascript
复制
@Query("DELETE from table WHERE id IN(:ids)")
int removeRows(List<Long> ids);

根据构建输出,如果我试图将返回类型包装在一个Deletion methods must either return void or return int (the number of deleted rows)中,就会得到Flowable

EN

回答 4

Stack Overflow用户

发布于 2017-10-12 14:24:52

正如在事务文档中指出的那样,您可以执行以下操作:

代码语言:javascript
复制
 @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);
     }
 }
票数 48
EN

Stack Overflow用户

发布于 2017-09-08 04:21:53

正如@CommonsWare所指出的,@Query是异步的,而@Insert、@Delete、@Update是同步的。

如果要在单个事务中执行多个查询,Room还提供了如下所述的方法。

代码语言:javascript
复制
roomDB.runInTransaction(new Runnable() {
        @Override
        public void run() {
            removeRows(ids);
            insertRows(ids);
        }
    });

我希望这能解决你的问题。

票数 32
EN

Stack Overflow用户

发布于 2020-01-28 15:08:38

对于Kotlin中的房间事务,您可以使用:

  • 实现方法的接口,如下所示:
代码语言:javascript
复制
@Dao 
interface Dao {

    @Insert 
    fun insert(item: Item)

    @Delete 
    fun delete(item: Item)

    @Transaction
    fun replace(oldItem: Item, newItem: Item){
        delete(oldItem)
        insert(newItem)
    }

}
  • 或者使用打开函数,例如:
代码语言:javascript
复制
@Dao 
abstract class Dao {

    @Insert 
    abstract fun insert(item: Item)

    @Delete 
    abstract fun delete(item: Item)

    @Transaction
    open fun replace(oldItem: Item, newItem: Item){
        delete(oldItem)
        insert(newItem)
    }

}

您将得到error: Method annotated with @Transaction must not be private, final, or abstract.而没有打开的修饰符。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44711911

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档