Room Database SQLite - 更新的门槛是多少?尝试循环执行 100 次更新
Room Database SQLite - What is the threshhold on updates? Trying to perform 100 updates in a loop
我基本上有 100 行需要立即更新。 SQLite 是否有每秒可以更新多少的阈值?如果它是 500 行会怎样?
我正在使用调用我的 Room Repo class 的 for 循环来进行更新。
for(Map.Entry<Integer, String> entry : itemsToUpdate.entrySet()) {
int id = entry.getKey();
String itemName = entry.getValue();
viewModel.updateMenuItem(id, itemName);
}
public Single<Integer> updateMenuItem(int menuItemId, String menuItemName){
return Single.fromCallable(() -> menuItemDao.updateMenuItem(menuItemId, menuItemName));
}
@Query("UPDATE menu_table SET itemName = :itemName WHERE id = :id")
int updateMenuItem(int id, String itemName);
如果其中一个更新失败,我将如何处理这种情况?
Does SQLite have a threshhold on how many you can update per second?
我认为没有固定的阈值,可以承担的金额将取决于可用资源。
相反,瓶颈可能是在事务中循环而不这样做。事务是一个工作单元,然后写入磁盘(瓶颈)。默认情况下,单个 SQL 语句是一个事务。所以 500 条语句的循环将导致 500 次写入磁盘(昂贵)。
将 500 条语句包含在单个事务中会大大减少磁盘空间 activity,我相信这就是您想要使用的。
- 注意@Transaction 注释,这只会将正在执行的语句放置在事务中(以及构建的任何基础语句,例如当查询访问@Relation 时)。
对于您的情况,需要在开始循环之前开始事务,然后在循环完成时结束事务。
因此,您可能需要以下内容:-
your_RoomDatase.beginTransaction();
for(Map.Entry<Integer, String> entry : itemsToUpdate.entrySet()) {
int id = entry.getKey();
String itemName = entry.getValue();
counter = counter + viewModel.updateMenuItem(id, itemName);
}
your_RoomDatabase.setTransactionSuccessful(); //<<<<<<<<<<< IF YOU WANT (see below)
your_RoomDatabase.endTransaction();
If one of the updates failed, how would I handle that scenario?
这取决于你所说的失败是什么意思。如果 ID 不存在,就 SQlite 而言,这不会构成失败,只是没有更新任何内容,更新返回的 int 将为 0。
但是,如果该值是一个外键并且该值不存在并且 onConflict 策略不是 IGNORE,那么结果将是外键冲突(异常)。
例外应该很少见。因此,假设失败意味着不更新并且您不想忽略更新不起作用。然后你可以计算返回 > 0 的次数(如果由 id 完成,则每次更新应该为 1 次)。如果这与尝试的次数不匹配,那么您可能不希望将事务设置为成功,然后事务将被回滚,即根本不会应用任何更新。
- 当然你可以处理极端之间的其他期望结果,但你可能想要维护一个 array/list 其中 id 有效或无效。
简而言之,您需要决定如何处理“失败更新”的策略。
您还应该在
查看其他与交易相关的方法
我基本上有 100 行需要立即更新。 SQLite 是否有每秒可以更新多少的阈值?如果它是 500 行会怎样?
我正在使用调用我的 Room Repo class 的 for 循环来进行更新。
for(Map.Entry<Integer, String> entry : itemsToUpdate.entrySet()) {
int id = entry.getKey();
String itemName = entry.getValue();
viewModel.updateMenuItem(id, itemName);
}
public Single<Integer> updateMenuItem(int menuItemId, String menuItemName){
return Single.fromCallable(() -> menuItemDao.updateMenuItem(menuItemId, menuItemName));
}
@Query("UPDATE menu_table SET itemName = :itemName WHERE id = :id")
int updateMenuItem(int id, String itemName);
如果其中一个更新失败,我将如何处理这种情况?
Does SQLite have a threshhold on how many you can update per second?
我认为没有固定的阈值,可以承担的金额将取决于可用资源。
相反,瓶颈可能是在事务中循环而不这样做。事务是一个工作单元,然后写入磁盘(瓶颈)。默认情况下,单个 SQL 语句是一个事务。所以 500 条语句的循环将导致 500 次写入磁盘(昂贵)。
将 500 条语句包含在单个事务中会大大减少磁盘空间 activity,我相信这就是您想要使用的。
- 注意@Transaction 注释,这只会将正在执行的语句放置在事务中(以及构建的任何基础语句,例如当查询访问@Relation 时)。
对于您的情况,需要在开始循环之前开始事务,然后在循环完成时结束事务。
因此,您可能需要以下内容:-
your_RoomDatase.beginTransaction();
for(Map.Entry<Integer, String> entry : itemsToUpdate.entrySet()) {
int id = entry.getKey();
String itemName = entry.getValue();
counter = counter + viewModel.updateMenuItem(id, itemName);
}
your_RoomDatabase.setTransactionSuccessful(); //<<<<<<<<<<< IF YOU WANT (see below)
your_RoomDatabase.endTransaction();
If one of the updates failed, how would I handle that scenario?
这取决于你所说的失败是什么意思。如果 ID 不存在,就 SQlite 而言,这不会构成失败,只是没有更新任何内容,更新返回的 int 将为 0。
但是,如果该值是一个外键并且该值不存在并且 onConflict 策略不是 IGNORE,那么结果将是外键冲突(异常)。
例外应该很少见。因此,假设失败意味着不更新并且您不想忽略更新不起作用。然后你可以计算返回 > 0 的次数(如果由 id 完成,则每次更新应该为 1 次)。如果这与尝试的次数不匹配,那么您可能不希望将事务设置为成功,然后事务将被回滚,即根本不会应用任何更新。
- 当然你可以处理极端之间的其他期望结果,但你可能想要维护一个 array/list 其中 id 有效或无效。
简而言之,您需要决定如何处理“失败更新”的策略。
您还应该在
查看其他与交易相关的方法