![](/img/trans.png)
[英]Reading different sets of data from same DB table by various java threads
[英]Two threads reading from the same table:how do i make both thread not to read the same set of data from the TASKS table
我有一個任務線程在Tomcat的兩個單獨實例中運行。 Task線程在特定條件下並發讀取(使用select)TASKS表,然后進行一些處理。
問題是,有時兩個線程都選擇同一任務,因此該任務被執行兩次。 我的問題是如何使兩個線程都不從TASKS表中讀取同一組數據
只是因為您的代碼(正在訪問數據庫)DAO函數未同步。使其同步,我認為您的問題將得到解決。
如果您提到的TASKS table
是數據庫表,那么我將使用事務隔離。
建議在事務內,將TASK table
的屬性設置為某個唯一的可識別值(如果未設置)。 提交筆跡。 如果一切正常,則該任務已由線程選擇。
我沒有遇到過這個用例,所以請用catuion來對待我的建議。
我認為您需要查看一些信息如何與任何企業作業計划程序一起使用,例如與Quartz一起工作
對於您的用例,有一個更好的工具可以完成工作-這就是消息傳遞。 您將保留需要處理的項目,然后嘗試同步工作線程之間的訪問。 在進行這項工作時,您需要解決許多問題-通常,更新表並從中進行選擇不應混在一起(它會鎖住),因此在那里存儲狀態是行不通的。 您的Java代碼中的同步也不會同步,因為那樣就無法在服務器重啟后幸存下來。
通過將JMS API與ActiveMQ等消息代理一起使用,您可以將消息發布到隊列中。 該消息將包含要執行的任務的詳細信息。 消息代理會將其持久保存在某個地方(在其自己的消息存儲庫或數據庫中)。 然后,工作線程將訂閱消息代理上的隊列,並且每條消息將僅移交給其中一個。 這是一個非常強大的模型,因為您可以有數百個消息使用者都在執行任務,因此可以很好地擴展。 您還可以使其具有所需的彈性,因此任務可以在Tomcat和代理重新啟動后繼續存在。
數據庫是否可以對此提供適當的管理,將在很大程度上取決於是否使用嚴格的兩階段鎖定(S2PL)或多版本並發控制(MVCC)技術來管理並發。 在MVCC下,讀取不會阻塞寫入,反之亦然,因此很有可能用相對簡單的邏輯來管理它。 在S2PL下,您將花費太多時間來阻止數據庫成為管理此數據庫的良好機制,因此您可能希望查看外部機制。 當然,不管數據庫如何,外部機制都可以工作,MVCC確實沒有必要 。
使用MVCC的數據庫是PostgreSQL,Oracle,MS SQL Server(在某些配置中),InnoDB(在SERIALIZABLE隔離級別上除外),可能還有許多其他數據庫。 (這些是我所知道的副手。)
對於所使用的數據庫產品,我沒有提供任何線索,但是如果是PostgreSQL,則可能要考慮使用咨詢鎖。 http://www.postgresql.org/docs/current/interactive/explicit-locking.html#ADVISORY-LOCKS我懷疑許多其他產品也有類似的機制。
我認為您需要一些變量(列),以保留行的最后修改日期。
您的線程可以讀取具有相同修改日期限制的同一組數據。
編輯:我沒有看到“不讀”
在這種情況下,您需要另一個表TaskExecutor(taskId,executorId),並且當某個線程運行task時,您會將數據放入TaskExecutor中。 當您啟動另一個線程時,它只是檢查任務是否已在執行(從RanTask中選擇...,其中taskId = ...)。 Нou還需要注意事務的隔離級別。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.