diff --git a/mozilla/calendar/providers/base/calProviderBase.js b/mozilla/calendar/providers/base/calProviderBase.js index b138d0e0cf6..9b1edfee16d 100644 --- a/mozilla/calendar/providers/base/calProviderBase.js +++ b/mozilla/calendar/providers/base/calProviderBase.js @@ -220,12 +220,21 @@ calProviderBase.prototype = { }, // void startBatch(); + mBatchCount: 0, startBatch: function cPB_startBatch() { - this.mObservers.notify("onStartBatch"); + if (this.mBatchCount++ == 0) { + this.mObservers.notify("onStartBatch"); + } }, endBatch: function cPB_endBatch() { - this.mObservers.notify("onEndBatch"); + if (this.mBatchCount > 0) { + if (--this.mBatchCount == 0) { + this.mObservers.notify("onEndBatch"); + } + } else { + ASSERT(this.mBatchCount > 0, "unexepcted endBatch!"); + } }, notifyOperationComplete: function cPB_notifyOperationComplete(aListener, diff --git a/mozilla/calendar/providers/storage/calStorageCalendar.js b/mozilla/calendar/providers/storage/calStorageCalendar.js index b8a3b32895a..be33135bc9f 100644 --- a/mozilla/calendar/providers/storage/calStorageCalendar.js +++ b/mozilla/calendar/providers/storage/calStorageCalendar.js @@ -104,6 +104,9 @@ const CAL_ITEM_FLAG_HAS_RELATIONS = 128; const USECS_PER_SECOND = 1000000; +var gTransCount = 0; +var gTransErr = null; + // // Storage helpers // @@ -2163,17 +2166,16 @@ calStorageCalendar.prototype = { flushItem: function (item, olditem) { ASSERT(!item.recurrenceId, "no parent item passed!", true); - this.mDB.beginTransaction(); + this.acquireTransaction(); try { - this.deleteItemById(olditem ? olditem.id : item.id, true /* hasGuardingTransaction */); + this.deleteItemById(olditem ? olditem.id : item.id); this.writeItem(item, olditem); - this.mDB.commitTransaction(); } catch (e) { - dump("flushItem DB error: " + this.mDB.lastErrorString + "\n"); - Components.utils.reportError("flushItem DB error: " + - this.mDB.lastErrorString); - this.mDB.rollbackTransaction(); + ERROR("flushItem DB error: " + this.mDB.lastErrorString + "\nexc: " + e); + gTransErr = e; throw e; + } finally { + this.releaseTransaction(); } this.cacheItem(item); @@ -2475,10 +2477,8 @@ calStorageCalendar.prototype = { // // delete the item with the given uid // - deleteItemById: function stor_deleteItemById(aID, hasGuardingTransaction) { - if (!hasGuardingTransaction) { - this.mDB.beginTransaction(); - } + deleteItemById: function stor_deleteItemById(aID) { + this.acquireTransaction(); try { this.mDeleteAttendees(aID); this.mDeleteProperties(aID); @@ -2487,15 +2487,12 @@ calStorageCalendar.prototype = { this.mDeleteTodo(aID); this.mDeleteAttachments(aID); this.mDeleteMetaData(aID); - if (!hasGuardingTransaction) { - this.mDB.commitTransaction(); - } } catch (e) { - Components.utils.reportError("deleteItemById DB error: " + this.mDB.lastErrorString); - if (!hasGuardingTransaction) { - this.mDB.rollbackTransaction(); - } + ERROR("deleteItemById DB error: " + this.mDB.lastErrorString + "\nexc: " + e); + gTransErr = e; throw e; + } finally { + this.releaseTransaction(); } delete this.mItemCache[aID]; @@ -2503,6 +2500,35 @@ calStorageCalendar.prototype = { delete this.mRecTodoCache[aID]; }, + acquireTransaction: function stor_acquireTransaction() { + if (gTransCount++ == 0) { + this.mDB.beginTransaction(); + } + }, + releaseTransaction: function stor_releaseTransaction() { + if (gTransCount > 0) { + if (--gTransCount == 0) { + if (gTransErr) { + this.mDB.rollbackTransaction(); + gTransErr = null; + } else { + this.mDB.commitTransaction(); + } + } + } else { + ASSERT(gTransCount > 0, "unexepcted batch count!"); + } + }, + + startBatch: function stor_startBatch() { + this.acquireTransaction(); + this.__proto__.__proto__.startBatch.apply(this, arguments); + }, + endBatch: function stor_endBatch() { + this.releaseTransaction(); + this.__proto__.__proto__.endBatch.apply(this, arguments); + }, + // // calISyncCalendar interface //