Как вы поддерживаете транзакцию indexeddb?

Вместо открытия нескольких транзакций (чтение таблицы, запись в таблицу, запись в другую таблицу и т. д.) возможно ли сделать все это из одной транзакции, если вы используете соответствующую IDBTransaction?

Mozilla говорит: «Единственный способ сохранить транзакцию активной — это сделать к ней запрос. Когда запрос будет завершен, вы получите событие DOM, и, если запрос выполнен успешно, у вас будет еще одна возможность продлить транзакцию. во время этого обратного вызова». что немного расплывчато. Означает ли это, что если я предоставлю обработчик событий для обратного вызова DOM, я смогу использовать транзакцию в любой момент этого обратного вызова, не беспокоясь о закрытии транзакции?

https://developer.mozilla.org/en/IndexedDB/Using_IndexedDB#Adding_data_to_the_database


person anonymous    schedule 30.04.2012    source источник


Ответы (4)


Транзакции IndexedDB фиксируются, как только срабатывает последний обратный вызов, поэтому способ сохранить их — передать их через обратные вызовы.

Я получаю информацию о транзакциях от Джонаса Сикинга, разработчика Mozilla и соавтора спецификаций для IndexedDB, который прокомментировал этот отличный пост в блоге, чтобы сказать следующее:

Следующее предложение неверно: «Транзакции сегодня автоматически фиксируются, когда переменная транзакции выходит за пределы области видимости и к ней больше нельзя отправить запросы».

Транзакция никогда не фиксируется автоматически, когда переменная выходит за пределы области видимости. Как правило, они фиксируются только тогда, когда срабатывает последний обратный вызов успеха/ошибки, и этот обратный вызов не планирует больше запросов. Так что это не связано с областью действия каких-либо переменных.

Единственным исключением является случай, когда вы создаете транзакцию, но не отправляете к ней никаких запросов. В этом случае транзакция «зафиксирована» (что бы это ни значило для транзакции, у которой нет запросов), как только вы вернетесь в цикл обработки событий. В этом сценарии вы могли бы технически «зафиксировать» транзакцию, как только все ссылки на нее выйдут за рамки, но это не особенно интересный вариант использования для оптимизации.

person buley    schedule 01.05.2012
comment
Означает ли последний абзац, что если вы создаете транзакцию ReadWrite, вы не размещаете к ней никаких запросов и не возвращаетесь к циклу событий перед созданием новой транзакции ReadWrite, то в основном вы получите потенциальную тупиковую блокировку/бесконечную запись голодание. - person lisak; 06.12.2014
comment
Еще один интересный вопрос. Что касается автоматической фиксации после успешного обратного вызова, что произойдет, если вы поставите новый запрос IDB в цикл обработки событий из обратного вызова, а не синхронно поместите новый запрос? В этом случае первый успешный обратный вызов немедленно возвращается, но запланирован другой запрос IDB. - person lisak; 06.12.2014
comment
Я задал новый вопрос, не могли бы вы взглянуть на него? stackoverflow.com/ вопросы/27326698/ - person lisak; 06.12.2014
comment
Я люблю, как в спецификации вы! Если у вас есть улучшения для моей библиотеки, пожалуйста, откройте вопрос на Github github.com/buley/dash/issues Я всегда занимался IDB, и вы будете ненавидеть этот совет, но: читайте спецификацию, но доверяйте своим глазам. Дайте спецификации изучить и спроектировать, но на практике эти вещи довольно странные, и тратить время только на изучение спецификации иногда может быть непродуктивно для вашей конечной цели - заставить что-то работать. - person buley; 07.12.2014

Краткий ответ: если вы предоставляете обработчик событий для события «успех» или «ошибка», вы можете поместить новый запрос в этот обработчик событий и не беспокоиться об автоматическом закрытии транзакции.

Длинный ответ: фиксация транзакций, как правило, должна быть полностью прозрачной. Единственное правило заключается в том, что вы не можете удерживать транзакцию открытой, выполняя «вещи», не связанные с базой данных. т.е. вы не можете начать транзакцию, а затем держать ее открытой, выполняя некоторые XMLHttpRequests или ожидая, пока пользователь нажмет кнопку.

Как только вы прекращаете размещать запросы к транзакции и завершается обратный вызов последнего запроса, транзакция автоматически закрывается.

Однако вы можете запустить транзакцию, использовать эту транзакцию для чтения некоторых данных, а затем записать некоторые результаты.

Поэтому убедитесь, что у вас есть все данные, которые вам нужны, прежде чем начать транзакцию, а затем выполните все операции чтения и записи, которые вы хотите выполнить в обратных вызовах запроса. Как только вы закончите, транзакция автоматически завершится.

person Jonas Sicking    schedule 15.06.2012
comment
спасибо, что заглянули - здорово, что рядом с нами околачивается автор спецификаций IDB - person buley; 16.06.2012
comment
В моем случае, который переносит целую кучу данных из websqldb в indexeddb, это означает, что я должен хранить все эти данные (возможно, много мегабайт) в памяти, прежде чем начинать сохранение с IndexedDB? Это отстой. - person oligofren; 02.04.2014
comment
Что касается автоматической фиксации после успешного обратного вызова, что произойдет, если вы поставите новый запрос IDB в цикл обработки событий из обратного вызова, а не синхронно поместите новый запрос? В этом случае первый успешный обратный вызов немедленно возвращается, но запланирован другой запрос IDB. - person lisak; 06.12.2014
comment
Я был бы рад, если бы вы могли взглянуть на вопрос, который я задал относительно поведения транзакций stackoverflow.com/questions/27326698/ - person lisak; 06.12.2014

Краткий ответ: не держите.

Чтобы предотвратить состояние гонки, IndexedDB разработан для неявной фиксации, и поэтому вы НЕ должны явно поддерживать транзакцию. Если это требуется, измените свой алгоритм, чтобы он не требовал его поддержания.

Повторно используйте транзакцию для повышения производительности и выполнения упорядоченных запросов. В этих случаях транзакция будет неявно поддерживаться.

person Kyaw Tun    schedule 27.05.2013

Чтобы транзакция оставалась активной, продолжайте выполнять следующие операции из обратных вызовов полной операции. См. следующий пример кода.

function put_data(db,tableName,data_array)
{
    var objectStore=db.transaction([tableName],"readwrite").objectStore(tableName);
    put_record(data_array,objectStore,num_rows,0);
}

function put_record(data_array,objectStore,row_index)
{
    if(row_index<data_array.length)
    {
        var req=objectStore.put(data_array[row_index]);
        req.onsuccess=function(e)
        {
            row_index+=1;
            put_record(data_array,objectStore,row_index);
        };
        req.onerror = function()
        {
            console.error("error", this.error);
            row_index+=1;
            put_record(data_array,objectStore,row_index);
        };
    }
}
person Ashish    schedule 20.12.2014