2008-11-17 43 views
11

我不敢在沒有事務的數據庫中做任何複雜的事情。幾乎總是有一個簡單的使用內置命令。但是當你開始處理其他持久性數據時,你就不會輕易使用事務支持。有些例子是數據庫以外是否需要事務性行爲?

  • 文件系統
  • Web服務(沒有,我用)

即使在非持久性數據常常是有用撤消工作塊,異常以下。用語言獲得的標準數據結構都不支持交易。

我想知道的是,爲什麼數據庫是特殊情況?

是否有任何有用的鏈接到數據庫外的事務行爲主題?

回答

15

我必須尊重不同意見:交易系統是不會自動和完全的數據庫引擎,恰恰相反......

我已經實現了應用程序事務機構的(.NET)是從一個數據庫事務不同。它實際上相當簡單(包括一個單元測試套件幾個小時的工作)。它完全用C#編寫,不依賴任何數據庫功能或任何其他組件。但首先有一些上下文...

這種非數據庫事務特性存在於Java平臺上的多種表現形式中,例如EJB,ESB,JMS,並且通常與BPM關聯。其中一些表現形式使用底層數據庫,但並非總是如此,也不是必然的。其他平臺具有可比較的表現形式,如MSMQ。

大多數舊版本控制系統不實現ACID事務語義。正如ddaa所說,CVS並不是Subversion(它的繼任者)。 Visual Source Safe不會。如果你研究Subversion,你可以找到比較圖表來說明這一點。

現在,對於關鍵點,數據庫事務或其等價物不保證安全的業務邏輯。儘管我喜歡Subversion,但具有諷刺意味的是這個事實的一個很好的例子。

你可以虔誠地使用Subversion以及自動構建腳本(一個編譯,測試和打包應用程序的命令),並且仍然向源控制存儲庫提交一個損壞的構建。我曾多次看過它。當然,使用非基於ACID事務的源代碼控制工具(如VSS)更容易。但是很多人知道使用Subversion這樣的工具是可能的。

請允許我佈置場景。你和同事正在開發一個應用程序,並使用Subversion作爲源代碼控制庫。你們都在編碼,偶爾會提交到存儲庫。您做了一些更改,運行一個乾淨的版本(重新編譯所有源文件),並通過所有測試。所以,你承諾你的改變並回家。你的同事一直在做他自己的改變,所以他也運行一個乾淨的構建,看到所有的測試通過,並提交到存儲庫。但是,你的同事然後從存儲庫中更新,做出更多更改,運行一個乾淨的構建,並且構建在他的臉上炸開!他再次從存儲庫中恢復他的更新(只是肯定),並發現乾淨的版本仍然爆炸!您的同事花費接下來的幾個小時對構建和源代碼進行故障診斷,最終發現您在離開之前所做的更改會導致構建失敗。他向你和你的共同老闆發出了一封討厭的電子郵件,抱怨說你破壞了構建,然後不小心回家了。你早上到達,找到你的同事和你的老闆在你的辦公桌旁等候你,其他人都在看!所以你快速運行一個乾淨的構建,並向他們展示構建沒有中斷(所有的測試都通過了,就像昨晚一樣)。

那麼,這怎麼可能?這是可能的,因爲每個開發人員的工作站不屬於ACID事務的一部分; Subversion只保證存儲庫的內容。當您的同事從存儲庫中更新時,他的工作站包含存儲庫內容(包括您的更改)和他自己的未提交更改的混合副本。當你的同事在他的工作站上運行一個乾淨的版本時,他正在調用一個不受ACID語義保護的業務事務。當他恢復變更並執行更新時,他的工作站隨後與存儲庫相匹配,但構建仍然失敗。爲什麼?因爲您的工作站也是單獨業務事務的一部分,與您對存儲庫的提交不同,它也不受ACID語義保護。由於在運行clean build之前,您沒有更新工作站以與存儲庫相匹配,因此實際上並沒有構建存儲庫中存在的源文件。如果您執行了此類更新,則會發現構建在您的工作站上也失敗。

現在我可以闡述我的初始觀點 - 交易的範圍/背景必須仔細考慮。僅僅因爲你有一個ACID事務並不意味着你的業務邏輯是安全的,除非ACID事務的範圍/上下文和業務邏輯完全匹配。如果您依賴於某種形式的數據庫ACID事務,但是您在業務邏輯中做了任何不在該數據庫事務處理範圍內的任何事情,那麼您就有一個可能導致類似和災難性錯誤的差距。如果您可以強制您的業務邏輯與您的數據庫事務完全匹配,那麼一切都很好。如果沒有,那麼你可能需要一個單獨的業務交易。根據不受保護邏輯的性質,您可能需要實現您自己的事務處理機制。

因此,消息傳遞可以是事務性的,但範圍僅僅是消息。關於上面的例子,Subversion的上下文只是個人提交到版本庫。但是,業務交易是一個乾淨的構建,涉及範圍更大。這個特殊的問題通常是通過將乾淨的構建與乾淨的結帳一起腳本化,理想地使用持續集成實現(例如,通過CruiseControl等)來解決。在開發人員工作站上,它要求每個開發人員在清理構建之前執行完整更新(甚至乾淨結賬)。

因此,回顧一下,每個事務都有一個範圍或上下文來限制其保護。業務事務通常包含超出我們常用的事務機制(如數據庫引擎)範圍的邏輯。你可能不得不彌補差異。在極少數情況下,編寫自己的事務處理機制可能更有意義。

我構建了一個適度的九十人公司的重要業務系統的重寫。我發現有必要實施這樣的機制,並且我發現這種體驗很簡單,有價值,也很有收穫。我會再做一次,也許更容易一點,但我總是會質疑爲什麼我不能堅持只是一個數據庫事務。

7

現代文件系統確實有交易。它們對最終用戶來說是透明的。

NTFS,XFS,JFS,EXT3和ReiserFS都行,只是僅舉幾例而已。

而這只是文件系統的內部。許多操作系統也支持文件鎖定(例如參見* NIX世界中的flock(2)),並使用獨佔(寫入)和共享(讀取)鎖定。

編輯: 如果你仔細想想,文件系統沒有像現代數據庫那樣的隔離級別,因爲一旦你讀完一個文件,如果你沒有鎖定它,傳統上你會關閉它。然後,當你想寫入它時,你重新打開它。

+0

文件鎖定不是事務,因爲沒有可能失敗的提交操作。 Downmodding。 – ddaa 2008-11-17 21:53:21

+0

確實,文件鎖不是事務性的,不是悲觀而是樂觀的,但是FS通常*由於性能原因而是事務性的。 – 2008-11-19 08:13:43

+0

@ddaa:錯了,苛刻。 – 2009-02-03 22:00:51

3

Subversion的提交是事務性的:他們是真正的原子,因此被中斷的承諾不離開倉庫在不一致的狀態。

+2

Subversion有一個數據庫後端。最初,它是bdb。由於它具有問題的可靠性,因此他們實施了自己的後端數據庫fsfs。一般來說,版本控制系統要麼是有缺陷的,要麼是數據庫支持的。 – ddaa 2008-11-19 20:17:09

5

Clojure使用Software Transactional Memory,它使用事務來簡化和安全地編寫無需手動鎖定的多線程程序。 Clojure具有不可變的數據結構,可變引用對象,並且需要事務來更改引用。

9

我認爲交易只能在數據庫中看到的原因是,根據定義,提供交易的系統稱爲數據庫。這聽起來很循環,所以我必須詳細說明。

交易支持是提供ACID屬性的功能。通俗地說,這意味着一個事務允許將許多謹慎的操作捆綁到一個包中,這個包要麼作爲一個整體成功,要麼作爲一個整體失敗。2.隱藏對併發用戶的未提交更改,以便3.併發用戶始終有一個「一致」的系統觀點。

Filesystems傳統上提供了一些鎖定機制,但這與提供交易不同。但是,所有文件系統都有一些原子屬性。例如,如果您有目錄/a//b/,並且您同時嘗試執行mv /a /b/amv /b /a/b,那麼只有其中一個操作會成功,而不會影響完整性。然而,文件系統通常缺乏的是將多個操作捆綁到一個孤立的原子包中的能力。

An answer提到Subversion。所有理智的版本控制系統都有交易。當提交到多個文件時,系統會完全應用提交,或者完全拒絕提交(CVS除外,我認爲它不是理智的)。拒絕的原因總是一個併發的變化。版本控制系統實現者非常關心維護數據庫。

Another回答提到的消息系統是事務性的。我沒有閱讀鏈接的材料,但答案本身只提到消息的原子傳遞。這不是交易。

我從來沒有聽說過Clojure之前Brian C.在這裏提到過。在我看來,它確實是在數據庫環境之外的事務的實現。這裏的重點是併發控制,而不是保持持久數據的一致性。

因此,除了Clojure之外,似乎任何需要事務的系統要麼使用底層數據庫,要麼變成數據庫。

1

我曾經需要將文件系統和數據庫視爲一個事務單元。

就我而言,我只需要將一組文件下載到文件系統中。我通過每次創建隨機目錄,將數據放在那裏並將目錄名稱存儲在數據庫表中來實現。因此,我所有的數據庫都可以工作,並且數據庫表(= filesystem work)中的目錄名稱可以在一個數據庫事務中完成。

http://www.databasesandlife.com/atomic-operations-over-filesystem-and-database/

相關問題