sqlite 跨DAO的Android Room事务

a8jjtwal  于 2023-08-06  发布在  SQLite
关注(0)|答案(3)|浏览(127)

官方文件指出:

It is recommended to have multiple Dao classes in your codebase depending on the tables they touch.

字符串
并且可以用Transaction注解标记一个方法,如下所示:

@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);
     }
 }


但是,如果一个事务跨越多个DAO呢?我是否应该将所有DAO合并为一个来支持事务,或者有更好的方法来实现这一点?

lawou6xi

lawou6xi1#

您可以使用RoomDatabase.runInTransaction(...)
例如:

database.runInTransaction(new Runnable(){
  @Override
  public void run(){
    Access all your daos here
  }
});

字符串

rn0zuynd

rn0zuynd2#

**事实1:**在方法上使用@Transaction会导致该方法在Dao_Impl生成的类中被覆盖。这个方法看起来像这样:

@Override
  public void makeFieldInactive(final long fieldId) {
      __db.beginTransaction();
      try {
          MyDao_Impl.super.makeFieldInactive(fieldId);
          __db.setTransactionSuccessful();
      } finally {
          __db.endTransaction();
      }
  }

字符串

**事实2:**runInTransaction()方法如下:

/**
 * Executes the specified {@link Runnable} in a database transaction. The transaction will be
 * marked as successful unless an exception is thrown in the {@link Runnable}.
 * <p>
 * Room will only perform at most one transaction at a time.
 *
 * @param body The piece of code to execute.
 */
@SuppressWarnings("deprecation")
public void runInTransaction(@NonNull Runnable body) {
    beginTransaction();
    try {
        body.run();
        setTransactionSuccessful();
    } finally {
        endTransaction();
    }
}

**更多信息:**我已经做了一些测试,似乎使用它们中的任何一个(或两个,冗余)将成功地导致你的道方法在一个事务中运行。
**答案:**在多个访问同一数据库的Daos中进行更改的方法上使用@Transaction是一种安全的方法,可以确保该方法中发生的所有数据库操作都发生在一个事务中。
编辑:一个方法访问多个Dao的示例,标记为@Transactoin:

@Transaction
 public void addItem(ItemEntity item) {
        item.setId(insert(item));
        ItemReportDao itemReportDao = AppDatabase.getIntance().itemReportDao();
        itemReportDao.addItemReport(item.getId());
}

v8wbuo2f

v8wbuo2f3#

你可以传递对dao的引用,比如函数的参数。

相关问题