2013-12-10 61 views
1

如何防止多個實例在不同的機器上同時運行。我想檢查是否有其他用戶實時工作在同一個實例上,而不是等待X時間。防止多個實例在不同的機器上同時運行

  • 我正在使用c#代碼。
  • 該實例連接到同一個數據庫。
+0

運行數據庫的數據庫系統是什麼? –

+0

SQL Server 2008 R2 – bebosh

回答

0

當您運行您的應用程序時,首先檢查是否沒有其他機器正在運行此應用程序,如果沒有,插入一個標識符,這意味着當前機器XX正在運行您的應用程序。當您關閉應用程序時更新您的數據庫(或刪除您的標識符),以便讓其他機器使用您的應用程序。

如果您想增加可靠性,可以每隔XX個時間單位向數據庫發送一些信號,以確認您的機器仍在使用您的應用程序,並且如果XX時間單位後沒有信號到達,讓其他機器選項使用你的應用。這種方法可以讓其他用戶使用你的應用程序,因爲某些機器關閉時沒有報告(例如連接問題)。

您可以做到更復雜,並在每次交易或每XX時間單位檢查您的機器是否仍有資格使用您的應用程序。

希望這有助於

0

有做一些這方面的很多方面都:

  1. 檢查Windows進程,你的應用程序必須運行過程中,如果具有相同名稱的過程中存在不啓動應用。
  2. 其次,如果用戶已經使用相同的用戶名和密碼登錄並再次使用該用戶名登錄並通過拒絕登錄,則維護已登錄的用戶詳細信息。
  3. 此外,您可以在登錄時獲取計算機名稱並保存登錄的用戶計算機名稱,並且如果用戶再次來自同一名稱,則拒絕它。
+0

你的第一個建議是錯誤的 - 他的應用程序運行在不同的機器上,所以檢查過程是否運行將不起作用 – Ofir

+0

第二和第三種方式也是錯誤的 - 我有更多的用戶名和密碼登錄到窗體和建議如果機器突然關閉而未進行註銷......建議機器網絡電纜是否已關閉。 – bebosh

0

在數據庫中創建鎖表:

Locks 
    LockId (primary key; not auto increment) 
    MachineId (this is a machine identifier; can be ip if in same network, MAC or a guid/string you set in your application's config file) 
    LockExpires (DateTime) 

您與一個記錄種子的鎖表。示例值:LockId = 1(可以是任何值),MachineId = null,LockExpires = null。

在您的程序硬編碼/配置種子的LockId,在您的查詢中使用它。

您將使用三種查詢設定/檢查/刪除鎖:

-- SetLock 
update Locks set 
    MachineId = {MachineId you configured for the machine}, 
    LockExpires = adddate(minutes, {N}, getdate()) -- lock for N minutes; set to null to hold the lock indefinitely) 
where 
    LockId = {hardcoded LockId} and 
    (
    MachineId is null -- nobody holds a lock 
    or LockExpires <= getdate() -- or lock expired 
    or MachineId = {MachineId you configured for the machine} -- or you hold the lock 
) 

-- CheckLock (if count > 0 then you hold the lock) 
select count(*) from Locks 
where 
    LockId = {hardcoded LockId} and 
    MachineId = {MachineId you configured for the machine} and 
    LockExpires > getdate() 

-- DeleteLock 
update Locks set 
    MachineId = null 
where 
    LockId = {hardcoded LockId} and 
    MachineId = {MachineId you configured for the machine} and 
    LockExpires > getdate() 

當程序啓動時,你是否有在同一臺機器上運行的實例(類似「How to determine if a previous instance of my application is running?」)。

如果您是此機器上的唯一實例,那麼您的SetLockCheckLock。如果CheckLock說你沒有鎖,那麼就出去別的了。

在您的應用程序中編寫代碼(最好在單獨的線程中)每隔(N - M)分鐘設置/檢查鎖定。其中N是您持有鎖的分鐘數,M是一些小數字(1或2),以確保您的鎖不會意外過期。

當您退出應用程序時,DeleteLock。請記住,如果您的應用程序崩潰,則不能運行其他實例,直到鎖定過期。在最壞的情況下,沒有應用程序將能夠運行N分鐘(當然,在最壞的情況下,您將LockExpires設置爲空,並且在您手動將MachineId手動更改爲空值之前不會運行應用程序)。

同樣,如果您沒有足夠頻繁地重置鎖,則您的鎖可能會在您重置密碼之前過期,而其他應用程序可能會在該時間範圍內運行。

因此根據您的偏好和編碼能力設置數字而不會出現錯誤:-)。如果沒有應用程序運行幾分鐘就可以生活,那麼N = 4到10和M = 1到2應該可以工作。

+0

我知道這種方式,但它與web應用程序的會話方式類似。 我想檢查用戶現在是否在實例上工作,意味着我不需要LockExpires – bebosh

+0

如果您試圖阻止同一用戶從不同的機器登錄,請將UserId替換爲MachineId。或者甚至同時使用(並相應地改變查詢),這樣你就可以告訴用戶他/她已經登錄了哪臺機器。 – Luc

-1

如果您正在使用的「SQL Server」,你可以設置你的數據庫爲「單用戶模式

在該模式中,只有當前連接被允許查詢或修改數據庫中的數據或模式。如果任何其他用戶或進程嘗試連接到數據庫,則會收到錯誤。

設置數據庫進入單用戶模式,最簡單的方法是使用下面的命令:

ALTER DATABASE database-name SET SINGLE_USER 

一切之前,你的程序應該檢查它是否可以能夠連接數據庫,如果連接建立,程序在這種情況下可以正常運行。

+1

我的問題是如何鎖定實例NOT鎖定數據庫,建議我想使用更多的實例工作相同的數據庫:) – bebosh

相關問題