Как поддържате жива 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