簡體   English   中英

jsp / servlets應用程序中的java方法和競爭條件

[英]java methods and race condition in a jsp/servlets application

假設我有一個名為doSomething()的方法,我想在多線程應用程序中使用此方法(每個servlet都繼承自HttpServlet)。我想知道在下列情況下是否可能出現競爭條件:

  1. doSomething() 不是staic方法 ,它將值寫入數據庫。
  2. doSomething()靜態方法,但它不會將值寫入數據庫。

我注意到我的應用程序中的許多方法可能會導致競爭條件或臟讀/寫。 例如,我有一個輪詢系統,並且對於每個投票操作,某個方法將更改該輪詢的單個單元格值,如下所示:

[poll_id |              poll_data        ]
[1       | {choice_1 : 10, choice_2 : 20}]

JSP / Servlets應用程序會自己解決這些問題,還是我必須自己解決所有問題?

謝謝..

這取決於doSomething()的實現方式和實際操作方式。 我假設寫入數據庫使用的JDBC連接不是線程安全的。 這樣做的首選方法是創建ThreadLocal JDBC連接。

至於第二種情況,它取決於方法中發生了什么。 如果它不訪問任何共享的,可變的狀態,那么就沒有問題。 如果是這樣,您可能需要適當地鎖定,這可能涉及向每個其他訪問這些變量的鎖添加鎖。

(請注意,僅將這些方法標記為已synchronized不會修復任何並發錯誤。如果doSomething()在共享對象上增加一個值,則需要synchronized對該變量的所有訪問,因為i++不是原子操作。如果是像遞增計數器這樣簡單的東西,你可以使用AtomicInteger.incrementAndGet() 。)

Servlet API當然不會神奇地使並發成為非問題。

寫入數據庫時​​,它取決於持久層中的並發策略。 悲觀鎖定,樂觀鎖定,最后勝利? 當你“寫入數據庫”時,你需要決定如何處理,還有更多的事情要做。 當兩個人同時點擊按鈕時你想要發生什么?

使doSomething靜態似乎對這個問題沒有多大影響。 正在發生的事情是相關部分。 它是修改靜態變量嗎? 然后是的,可能會有競爭條件。

servlet api不會為你做任何事情讓你的並發問題消失。 在servlet上使用synchronized關鍵字這樣的事情是個壞主意,因為你基本上強迫你的線程一次處理一個,這會破壞你對多個用戶快速響應的能力。

如果使用Spring或EJB3,則任何一個都將提供線程本地數據庫連接以及指定事務的能力。 你一定要看看其中一個。

情況1,您的servlet使用一些訪問數據庫的代碼。 數據庫具有您應該利用的鎖定機制。 這有兩個重要原因:數據庫本身可能會從其他讀取和寫入數據的應用程序中使用,但這還不足以讓您的應用程序處理與自身競爭的問題。 而且:您自己的應用程序可能會部署到一個擴展的集群Web容器中,其中您的代碼的多個副本在不同的計算機上執行。

因此,有許多標准模式可以處理數據庫中的鎖,您可能需要閱讀悲觀和樂觀鎖定。

servlet API和JBC連接池為您提供了一些有用的保證,這樣您就可以在不使用Java同步的情況下編寫servlet代碼,前提是您的變量在方法范圍內,在概念上您有

   Start transaction (perhaps implicit, perhaps on entry to an ejb)
   Get connection to  DB ( Gets you a connection from pool, associated with your tran)
   read/write/update code
   Close connection (actually keeps it for your thread until your transaction commits)
   Commit (again maybe implictly)

因此,您唯一真正的問題是處理數據庫中的任何爭用。 以上所有這些都傾向於使用諸如JPA之類的東西更好地完成,但是在或多或少的情況下正在發生的事情。

案例2:靜態方法,這可能意味着您現在將所有內容都保存在內存結構中。 這(禁止某種遠程調用)會影響單個JVM並管理您自己的鎖定。 如果您的JVM或機器崩潰,我猜您會丟失數據。 如果您關心數據,那么使用數據庫可能會更好。

或者,如何完全采用其他方法:servlet通過將消息寫入持久性JMS隊列來簡單地記錄“投票”。 讓一些其他進程從隊列中獲取投票並添加它們。 您不會以這種方式立即向選民提供反饋,但您將用戶的體驗與實際(在類似場景中)相當復雜的處理分離。

我認為你的問題的最佳解決方案是使用“synchronized”關鍵字和wait / notify之類的東西!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM