Я использую базу данных комнат на Android. В базе данных я пишу показания датчиков (ускорение, гироскоп, и т. Д. c.) С высокой частотой. Для повышения производительности я создал менеджер транзакций, состоящий из фиксированного размера ArrayBlockingQueue
. Если очередь заполнена, элементы очереди записываются в транзакции в базу данных. Проблема заключается в том, что insert()
будет блокироваться, когда транзакция выполняется (и если она не будет блокироваться, а скорость записи значений в очередь быстрее, чем получение значений из очереди, транзакция никогда не будет завершена sh). Код показан ниже.
Другой вариант - создать неограниченный LinkedBlockingQueue
и получить поток, извлекающий элемент из очереди, как только элемент окажется в очереди. Если поток использует указанное количество элементов, поток будет фиксировать транзакцию, начинать новую транзакцию и снова потреблять элементы из очереди. Таким образом, очередь никогда не блокируется, но очередь может расти бесконечно, что может привести к проблемам с памятью.
Какой лучший способ реализовать это?
public class TransactionManager{
private Database db;
private BlockingQueue<DatabaseEntities.DatabaseEntry> queue;
private int size;
TransactionManager(int queueSize, Database db){
queue = new ArrayBlockingQueue<>(queueSize);
size = queueSize;
this.db = db;
}
void insert(DatabaseEntities.DatabaseEntry entry){
queue.add(entry);
if(queue.size() >= size){
db.runInTransaction(new Runnable() {
@Override
public void run() {
DatabaseEntities.DatabaseEntry tmp;
while ((tmp = queue.poll()) != null){
tmp.dao.insert(tmp);
}
}
});
}
}
void flush(){
db.runInTransaction(new Runnable() {
@Override
public void run() {
DatabaseEntities.DatabaseEntry tmp;
while ((tmp = queue.poll()) != null){
tmp.dao.insert(tmp);
}
}
});
}
}