2016-01-24 73 views
5

我正在努力弄清楚我想在更改數據庫後使用的命令。我正在通過SQLite3和db-aware控件學習,這裏是我的理解......Post,ApplyUpdates和Commit對數據庫有什麼區別?

當用戶在db-aware控件中鍵入某些內容(或者將內存數據集放入編輯狀態)時,POST將存儲記憶力的變化。控件通常會自動或隱式地爲您執行此操作。

儘管您必須在任何地方識別任何更改之前發佈,但這些更改尚未發送到磁盤上的實際數據庫文件。他們只在記憶中。發送更改到磁盤需要APPLYUPDATES

即使在通過APPLYUDATES發送到磁盤上的文件後,它們仍可以仍然被更改或回滾。這就像打開撤消。在調用COMMIT之前,它們不會永久保存到磁盤。

聽起來不錯?我真的很想知道我在做什麼,所以我不只是複製和粘貼代碼。但請隨時在您的回覆中複製,粘貼和編輯我的嘗試。

+0

您可能不需要在Delphi代碼中調用Commit。服務器連接可以(默認配置爲)將隱式事務中提交給服務器的更改包裝起來。對於沒有真正服務器的SQLite,只有一個Dll,它可能依賴於你正在使用的TDataSet-descendant組件 - 檢查他們的文檔或源代碼。 – MartynA

回答

10

您的問題的答案是Post,ApplyUpdates和Commit做了完全不同的事情,通常發生在數據庫應用程序的不同位置(進程)和上下文中。

PostApplyUpdates都是真正的客戶端操作,而Commit是可能(或不)需要顯式調用服務器端完成交易的SQL操作。

如果您考慮使用三層服務器,最容易理解這些差異。 SQLite有點古怪,因爲它不是一個真正的Sql Server,它被設計用來響應不同進程在不同計算機上的調用(儘管它可以做爲三層系統的後端)。

關於最簡單的傳統3層安排有一箇中間層的Delphi服務器,位於Sql Server(例如MS Sql Server)和客戶端(通常是客戶機上運行的Delphi程序)之間。Borland/EMBA的傳統技術來實現,這是DataSnap

客戶層通常包含TClientDataSet(或第三方等效),從通過在中間層服務器的特殊TDataSet的後裔後端SQL服務器接收數據。雖然獲得數據f從Sql Server到中間層通常涉及Sql Server上的事務,一旦數據全部加載到客戶端層中的CDS中,SQL Server上就沒有待處理的事務(除非您竭盡全力保留一個在服務器上打開的事務,對服務器的其他用戶不友好並佔用服務器上的鎖定資源,這是有限的)。

在CDS(或實際上任何TDataset後代)中編輯數據時,會將數據集置於dsEdit狀態(請參閱TDataSetState的聯機幫助)。所做的更改是臨時的,這意味着它們可以在CDS中撤消,直到您調用.Post,它將它們保存到CDS的Data(對於TClientDataSet,對客戶端數據的更改可以在調用後回滾事件。發佈,只要.ApplyUpdates尚未被調用)。請記住,在客戶端層的CDS上調用.Post時,Sql Server上沒有掛起事務(或者至少不應該有)。

調用.Post確實而不是導致更改傳播回對應的中間層數據集。要啓動這個功能,您可以在客戶端CDS上調用ApplyUpdates,該應用程序將中間層中的TDataSetProvider傳遞給CDS與中間層的面向服務器的數據集。它是DataSetProvider(或者更準確地說是一個與之關聯的TSqlResolver),它生成實際發送給SQL服務器的SQL,以便將更改應用到SQL數據庫。因此,在一個標準的DataSnap 3層設置中,您無法直接控制Commit是否被調用。

Commit是由Sql Server執行的SQL操作,作爲完成交易的兩種可能方式之一(另一種是Rollback)。使用MS Sql Server f.i.,可以將與服務器的連接配置爲自動將收到的UPDATEINSERTDELETE語句包裝在隱式事務中。

您需要關注事務控制的程度取決於您正在使用的後端服務器以及您的應用程序在與其他服務器數據的併發性方面的要求。如果您對SLite處理事務感興趣,請參閱您正在使用的DBcomponents或其源代碼的文檔。

一些用於處理真正SQL Server的Delphi組件庫確實支持用於控制服務器端事務的公開設施,例如, Interbase的IBX版本。

順便說一句,用德爾菲的術語來說,CachedUpdates是來自長期過時的BDE的暫停,這是Borland在各種後端服務器的公用DB訪問框架上的首次嘗試。它繼承了一些TDataSet後裔的實現,並且(令人遺憾的是,imo)在FireDAC-- EMBA最新的跨數據庫產品中取得了一些成果。

+1

感謝您提供豐富的回覆。這很有幫助。 ...只是爲了跟進,如果服務器要求我發送一個「COMMIT」命令,它會在「ApplyUpdates」之前還是之後,你認爲呢?好像它會在呼叫發送更新到主服務器之前編碼。 –

+0

如果您專門指向後端服務器的SQL COMMIT語句,則必須在** ApplyUpdates之後爲**,因爲直到ApplyUpdates被執行爲止,必需的SQL UPDATE命令纔會發送到後端服務器以進行COMMIT-ed處理的更改。 – MartynA

-1

當您使用ApplyUpdates時,必須將CachedUpdates 屬性設置爲True。然後 你可以使用post,delete(和其他)來改變你的數據,這些 的修改首先會被放入一個緩存中。 調用ApplyUpdates時,所做的所有更改都存儲在 數據庫中。隨着取消更新 你可以撤消你所做的所有更改。 當您將CachedUpdates屬性設置爲false時, 所做的所有更改將直接存儲在數據庫中,並將被 。不能使用命令ApplyUpdate和CancelUpdates,不能使用 。

+1

那麼,「COMMIT」做了什麼? –

+0

使用COMMIT語句結束當前事務,並永久保存事務中執行的所有更改以保存更改。 –

+1

感謝您花時間回覆我,Iresha, –

相關問題