簡體   English   中英

從同一表讀取兩個線程:如何使兩個線程不從TASKS表讀取同一組數據

[英]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.

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