Менеджер транзакций базы данных, использующий очередь в Android - PullRequest
0 голосов
/ 16 апреля 2020

Я использую базу данных комнат на 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);
                }
            }
        });
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...