2009-11-01 65 views
0

我在我的Web應用程序中使用Spring,底層數據庫爲Sybase。與Sybase的Spring交易

我有3個複雜的存儲過程被執行。 的特效,有創建表DROP TABLE命令舉行的臨時結果集。

這些表在用戶分貝空間中創建的,而其在tempdb空間。因此,我面臨着需要確保從服務bean(將有DAO對象調用存儲過程)的整個服務操作序列化。是否簡單地使服務bean方法成爲一個Spring Transaction,確保在我的情況下解決潛在的併發相關問題?

,我注意到的是,我的註解服務方法@Transactional,取得了Sybase數據庫拋出一個錯誤另一件事:「CREATE TABLE命令不能在事務內執行。」這是否意味着Spring使整個數據庫操作成爲事務? 我真的不清楚這一點,任何解釋都會受到歡迎。 含義如果我有一個名爲myproc的存儲過程。 sybase語句將爲exec myproc。這就是說,由服務方法中的DAO對象執行,註釋爲@Transactional。現在,春天在什麼使數據庫操作「的begin tran 高管在myproc 結束TRAN」。我的觀察似乎表明這一點。請解釋。

而且也解釋了,如果@Transactional的只是註釋,能解決我的併發問題。我實際上不希望我的存儲過程的兩個實例一次在數據庫上運行。

+0

創建的表的名稱是否以#符號開頭?這些名稱是固定的,還是以某種方式按照每個請求生成的? – 2009-11-01 22:50:42

+0

這些表不加前綴#,即表在用戶數據庫空間中創建,而不是在tempdb空間中創建。名稱是固定的,儘管表模式是根據請求動態生成的。 – 2009-11-02 15:59:52

+0

DDL(如創建和刪除表語句)通常會執行隱式提交,因此您不能將其作爲事務性語句的一部分,因此不會出現此錯誤。 – 2009-11-16 01:20:45

回答

0

你已經問了一些一次性的問題,但我會盡我所能來回答他們。

  • 標記服務,因爲它@Transactional與當前的JTA(Java事務API)關聯交易(或創建一個如果需要的話)
  • 根據您的數據源是如何配置,JDBC連接通常也被關聯(列入交易
  • 如果連接與JTA事務關聯,則在其上執行的任何事情都將在數據庫事務中發生。
  • 在Sybase ASE中,您不能在事務內創建(或刪除)表。

因此,將您的服務標記爲@Transactional將阻止您執行包含create table語句的proc。

但是,這並不能解決你面臨的問題。 標記@Transactional,僅表示它在JTA事務中執行。這意味着它要麼提交,要麼回滾,但它並不防範併發訪問。

您有幾種選擇

  • 如果你知道你的應用程序將永遠只能在單個虛擬機上運行,​​那麼你可以標記代碼serialized。這將確保虛擬機一次只有該代碼中有1個線程。
  • 您可以在proc中實現併發控制(例如使用lock table),但這需要一個事務,這將阻止您在過程中創建表。
  • 或者您可以重新設計您的應用程序,不必跳過所有這些箍筋。

可能有更簡單的方法來實現您正在尋找的結果 - 在proc中創建和刪除表,然後嘗試阻止併發訪問該proc並不是解決問題的典型方法。