2013-07-10 61 views
0

我有以下代碼:卡宴執行上的CommitChanges)INSERT查詢(

List<Assignment> assignments = objectContext.performQuery(assignmentQuery); 
objectContext.commitChanges(); 
objectContext.deleteObjects(assignments); 
objectContext.commitChanges(); 

我做的第一commitChanges()提交的所有查詢。然後我清除卡宴的日誌。在第二個commitChanges(),這顯示在日誌上:

信息:QueryLogger.logBeginTransaction:2013-07-10 07:37:11,214:---事務已啓動。 INFO:QueryLogger.logQuery:2013-07-10 07:37:11,218:INSERT INTO scheduler_assignment ... INFO:QueryLogger.logQuery:2013-07-10 07:37:11,241:DELETE FROM scheduler_assignment ... INFO:QueryLogger.logCommitTransaction:2013-07-10 07:37:11,286:+++事務已落實。

我不明白爲什麼它在我試圖刪除時正在執行INSERT語句。誰能解釋一下?謝謝!

回答

1

唯一合乎邏輯的解釋是你的ObjectContext是「髒的」 - 除了這裏顯示的東西外,它還包含其他未提交的對象。這可能是由於各種原因發生的,其中最常見的有兩種:

(1)ObjectContext範圍太寬,對上下文的更改來自應用程序中的其他位置。

(2)在提交期間更改來自回調/偵聽器。

上ObjectContexts的範圍界定的一些提示:

  • 如果上下文預計處理寫入操作(而不是僅僅讀;只讀上下文可以共享)在併發環境不共享ObjectContexts。
  • 處理寫入的ObjectContext的理想範圍是單個方法或單個請求。這保證了其他人不會同時訪問它。
  • 雖然上下文通常會有更長的範圍。例如。它可能被保存在一個webapp的會話中,並且可能會在請求之間傳送未提交的更改。在這種情況下,仍然考慮縮小範圍。例如。在會話中創建多個此類上下文,每個上下文都附加到給定頁面。所以當你在別的地方提交別的東西時,一個地方的未定義變化並不會讓你感到驚訝。
+0

感謝您的回答。你對第一次調用'commitChanges()'後爲什麼仍然包含未提交的對象有任何理論嗎?第一次調用不應該通過所有未被滿足的對象並提交它們嗎? – Tuan

+0

是的。第一次提交後,您應該得到一個乾淨的上下文或一個異常。嘗試在提交#1之後調用context.newObjects(),然後在提交#2之前查看是否有任何內容。說實話,我仍然無法想象除了某些其他線程同時添加這些對象之外的任何其他原因。也是實際代碼上方還是在實際應用程序的2個提交之間發生了其他事情? –

+0

只是想到了另一個可能的原因 - 你有Assignment實體上的@PreRemove回調或者監聽器嗎?那些可能會觸發並創建對象(如果有代碼可以這樣做的話) –