2012-06-27 57 views
0

假設我有一個有訂單行的訂單,並且我們有一個多用戶系統,其中不同的用戶可以添加訂單行。訂單持續到數據庫確保業務規則不被多個用戶破壞

一個業務規則是隻能爲訂單創建10個訂單行。

我的選擇是確保這個規則不被破壞?我是否應該檢查內存並應用鎖定還是通過過程在數據庫中處理?

+0

數據庫約束(很難實現)如何?看到我的貢獻在這裏:http://stackoverflow.com/a/11210474/905902 – wildplasser

+0

可以刪除orderlines嗎? –

+0

是的,他們可以被刪除。 –

回答

2

關於如何處理這個問題,您有很多選項,包括:觸發器,約束,業務規則邏輯和數據結構。

我的偏好如下。在存儲過程中包裝所有對訂單行的插入/刪除/更新,並僅通過存儲過程爲應用程序層提供對錶的訪問權限。然後該過程可以執行這個和其他業務規則。它還會在運行時鎖定表進行更新,因此只有一個用戶可以在任何給定的時刻更改表。

類似的方法是在表上插入一個替代觸發器。這會導致在此(和其他)業務規則失敗時插入失敗。主要關心的是可維護性。一張桌子上的一個觸發器很好。但是,如果您開始爲具有級聯插入/刪除的多個表執行此操作,則最終可能會觸發惡夢。

您可以嘗試使用約束來做到這一點,如其中一條評論所暗示的。你一定會想要測試這個性能,因爲你很難控制如何實現約束。

此外,您可以在訂單表中有十個orderline列。這將強調執行這一規則。但是,對於每個訂單行都有單獨的列,並且需要處理諸如刪除之類的問題,這是有成本的。

另一種選擇,在這種情況下不適用,是在應用程序級別強制執行業務規則。但是,對於多個併發用戶,您應該在數據庫中完成這項工作。

+0

謝謝你的回答。爲什麼不使用臨界區/互斥鎖在應用程序級別執行此操作? –

+1

只是因爲數據庫可以支持這個功能。爲什麼在應用程序已經在使用可以做到這一點的數據庫時向開發環境引入另一個元素? –

+3

我同意戈登。將SP視爲對象上的方法,並且該對象本身負責維護其自己的狀態。如果數據庫將通過多個應用程序共享,並且具有多個代碼庫,則尤其如此。 ***但是,如果***只有一個應用程序,那麼只有一個代碼庫,在該單一應用程序中使用ORM或其他抽象層是維護數據完整性的同等可管理模式。即使如此,多個應用程序實例的併發性通常更容易在數據庫本身中處理。 – MatBailie

1

假設最糟糕的情況是,大量用戶(又名2位以上用戶)都在同時嘗試將行添加到單個訂單中。 (更糟的是,假設他們都試圖添加不同數量的行,但一次不超過10行 - GUI至少可以控制這麼多)。這導致了類似的情況:

  • A檢查是有她的行空間,獲取確定
  • 乙檢查是有他的行空間,獲取確定
  • A將她排,生活是美好的
  • B再加上他的行,現在有11
  • 所有這一切都拿了第二

不到十分之一內進行,以避免這種情況,需要有某種形式的中央「檢查點「或調節器,所有用戶都可以確定它們是否可以添加行。如果他們通過檢查站,他們可以添加;如果不通過,他們不能。檢查點必須是絕對的:一旦批准被接收/分配,該決定影響所有後續檢查(即,當你檢查並被授予第十行時,其他人以前沒有被授予它,並且隨後將沒有其他人被授予它) 。

有幾種實現方法,它們都涉及數據庫事務(ACID屬性)。事務處理必須儘可能簡短,以避免與其他用戶阻塞或死鎖。這可能是棘手的代碼,對於我的錢來說,實現/控制過程的最佳方式是通過存儲過程(如@Gordon Linoff所說)。

+0

悲觀鎖定工作? –

+2

會,但是您應該考慮(實際上非​​常常見)的情況,其中一個用戶開始編輯(放置鎖定)並去午餐。更好的辦法是使用存儲過程並進行適當的鎖定(您需要鎖定訂單本身,而不是行)。定期更新用戶顯示屏上的訂單狀態(行數)也會有所幫助。 – Arvo

+0

與@Arvo的完全協議。 –