2009-01-30 44 views
4

對於另一個問題,我遇到了一個誤解,這似乎偶爾會出現在SO這裏。有些提問者似乎認爲觸發器是作爲事件對OOP的數據庫。我需要一個類比:觸發器和事件

有沒有人有一個很好的比喻來解釋爲什麼這是一個有缺陷的比較,以及誤用它的後果?


編輯:

比爾K.正確地打它,但也許沒有看到的事件和給我的印象,反正回調函數之間的關鍵differeence的重要性。每次事件發生時,觸發器都會導致代碼執行;回調只發生在一個事件已被註冊的情況下(絕大多數事件都不是這樣);即使如此,在大多數情況下,回調的第一個動作是註銷自己(或至少回調中包含限定出口,因此它只能執行一次)。

如果您編寫觸發器,它會在每次事件發生,因爲沒有辦法註冊或取消註冊代碼段。

觸發器是一種將重複邏輯同步插入執行線程(即同步)的方法。事件是延遲邏輯直到以後的一種手段(即實現異步性)。

在這兩種情況下都有例外和緩解,但觸發器和回調的基本模式在意圖和實現方面大多相反。通常這種區別似乎並沒有完全沉入。(恕我直言,YMMV)。 :D

回答

8

它們不是一回事,但它們並不無關係。

  • 的代碼塊的一些聲明瞭狀態的變化「利息」:

    在這兩種情況下,該機構可以大致如下所述。

  • 您的應用程序會影響一些更改。
  • 系統運行代碼塊以響應更改。

也許數據庫觸發器更像是一個回調函數,它在特定事件中註冊了興趣。

下面是一個類比:事件是一個橡膠球,你扔。觸發器是一隻追逐拋球的狗。

如果還有一些其他的差異,你記住它使得它「危險」(注意:OP已經編輯了這個選擇的話),以比較觸發器和事件,你可以描述你的意思。


觸發器是夾着 同步重複邏輯進入 線程執行(即 同步)的方式。事件是 推遲邏輯的手段,直到後來(即 實現異步性)。

好的,我明白你的意思了。但我認爲這在某些方面受制於實施。我不會假設事件處理程序必須註銷自己;這取決於您使用的系統。例如,一個UNIX信號處理程序必須防止自己在處理一個新信號時捕捉到新信號。但是Tomcat容器內的Java servlet應該是線程安全的,因爲它可能會被多個線程同時調用。他們都是不同種類的事件處理程序。

事件處理程序可能是同步的或異步的。發佈/訂閱系統中的處理程序是否可以讀取最近發佈的消息,但在處理程序註冊之前?或者只有同時發佈的消息?


有從事件處理程序處理的觸發不同的另一個重要原因是:我經常建議在影響數據庫外部狀態的觸發做任何事情。

例如,發送電子郵件,寫入文件,發佈到Web服務或分支進程在觸發器內不合適。如果沒有其他原因產生觸發器的事務可能會回滾,但無法回滾這些外部影響。您甚至可能不使用顯式事務,但是說您在BEFORE觸發器中發送電子郵件,但由於NOT NULL約束或其他原因,操作失敗。

相反,所有這些工作都應該通過應用程序中的代碼完成,之後已確認SQL操作成功並且已提交事務。

這真是太糟糕了,人們一直試圖在觸發器內做不合適的工作。 MySQL的高級開發人員推動UDF在memcached中讀取和寫入數據。哇 - 我只注意到這些有made it into the MySQL 6.0 product!令人震驚!

因此,這裏是在比喻的又一次嘗試,比較觸發器和事件以刑事審判的過程:

  • BEFORE觸發器是指控。
  • AFTER觸發器是起訴書。
  • COMMIT是有罪判決後的定罪。
  • ROLLBACK是無罪裁決後的無罪釋放。

你只是想在罪犯被定罪後將他們關進監獄。

  • 鑑於事件本身就是犯罪。
+0

我相信'他'指的是某些cavelier的態度,以什麼資金有意義的觸發 – 2009-01-30 08:25:16