2016-10-28 2 views
1

이 라인에서 :색인화 : TransactionInactiveError

var request = store.add(obj); 

나는 오류를 얻을 :

TransactionInactiveError: A request was placed against a transaction which is currently not active, or which is finished.

나는 단지 내가 AJAX를 사용할 때 오류가 발생합니다. 트랜잭션이 완료되기 전에 AJAX가 완료되었는지 어떻게 확인합니까? objectstore에 SQL 데이터베이스의 정보를로드하려고합니다. 오류를봤을 때 트랜잭션과 비동기 성격에 대한 정보를 얻을 수 있지만 코드가있는 구체적인 솔루션을 찾지 못했습니다.

콜백, 약속 및 타임 아웃 (해킹 같은 느낌)을 들여다 보았지만이 비동기 호출이 작동하지 않습니다. 어떤 도움이라도 대단히 감사하겠습니다.

var req = indexedDB.open(DB_NAME, DB_VERSION); 
req.onsuccess = function() { 
     db = this.result; 
     var tx = db.transaction('tblFields', 'readwrite'); 
     var store = tx.objectStore('tblFields'); 

      $.ajax({ 
        type: "POST", 
        url: "Off.aspx/GetFields", 
        data: '{}', 
        contentType: "application/json; charset=utf-8", 
        dataType: "json", 
        success: function (response) { 
         var customers = response.d; 
         $(customers).each(function() { 
          var obj = { measureID: this.measureID, measureName: this.measureName, fieldName: this.fieldName }; 
          var request = store.add(obj); 
         }); 
        }, 
        failure: function (response) { 
         alert(response.d); 
        }, 
        error: function (response) { 
         alert(response.d); 
        } 
       }); 
} 

답변

1

성공 콜백이 비동기 적으로 실행됩니다. 콜백으로 트랜잭션 초기화 코드를 이동하면이 문제를 해결해야합니다

success: function (response) { 
    var customers = response.d; 
    var tx = db.transaction('tblFields', 'readwrite'); 
    var store = tx.objectStore('tblFields'); 
    $(customers).each(function() { 
     var obj = { measureID: this.measureID, measureName: this.measureName, fieldName: this.fieldName }; 
     var request = store.add(obj); 
    }); 
}, 
0

색인화가 짧은 시간 후 종료 트랜잭션에 대한 활성 요청을 감지하지 않는 경우. Ajax 요청을하면 즉시 응답을 얻지 못한다. ajax 요청을 작성하고 응답을받는 사이에 idb는 트랜잭션을 사용하는 활성 idb 요청을 볼 수 없으므로 트랜잭션을 닫습니다.

해결책은 간단합니다. 먼저 ajax 요청을 수행 한 다음 idb 트랜잭션을 수행하십시오. 여기에 몇 가지 의사 코드는 다음과 같습니다

function dbconnect(name, version, upgrade) { 
    return new Promise(function(resolve, reject) { 
    var request = indexedDB.open(name, version); 
    request.onupgradeneeded = upgrade; 
    request.onsuccess = function(event) { 
     var db = event.target.result; 
     resolve(db); 
    }; 
    request.onerror = function(event) { 
     var error = event.target.error; 
     reject(error); 
    }; 
    request.onblocked = function(event) { 
     console.warn('blocked, not fulfilling promise until unblocked'); 
    }; 
    }); 
} 

function ajaxpostrequest(url) { 
    return new Promise(function(resolve, reject) { 
    $.ajax({ 
     type: 'post', 
     data: '{}', 
     contentType: 'application/json; charset=utf-8', 
     dataType: 'json', 
     url: url, 
     success: resolve, 
     failure: reject, 
     error: reject 
    }); 
    }); 
} 

function addcustomer(db, customer) { 
    return new Promise(function(resolve, reject) { 
    var tx = db.transaction(...); 
    var store = tx.objectStore(...); 
    var obj = {measureId: customer.measureId, ...}; 
    var request = store.add(obj); 
    request.onsuccess = function(event) { 
     resolve(); 
    }; 
    request.onerror = function(event) { 
     reject(event.target.error); 
    }; 
    }); 
} 


async function request_then_connect_then_put() { 
    try { 
    var response = await fetch(url, {method:'post'}); 
    console.log('fetched url'); 
    var json = await response.json(); 
    var customers = json.d; 
    console.log('read json object from text of url'); 
    var db = await dbconnect(...); 
    console.log('connected to database', db.name); 
    var addpromises = customers.map((customer) => addcustomer(db, customer)); 
    var result = await Promise.all(addpromises); 
    console.log('stored all customer object things'); 
    } catch(error) { 
    console.debug(error); 
    } 
} 
: 당신이 약속을 사용하고 ES6에 액세스 할 수있는, 이런 일을하고 싶은 경우

$.ajax({ 
    success: function(response) { 
    var req = indexedDB.open(...); 
    req.onsuccess = function(event) { 
     var db = event.target.result; // or this.result, or req.result 
     var tx = db.transaction(...); 
     var store = tx.objectStore(...); 
     for(var customer of response.d) { 
     var obj = {...}; 
     store.add(obj); 
     } 
    }; 
    } 
}); 

관련 문제