2014-10-28 41 views
0

我目前正在開發一個我們想要開發的應用程序的C#項目。我們正在就用戶之間共享數據的問題進行頭腦風暴。我們希望能夠指定一個文件夾,其中應用程序的所有文件將被保存,並且我們希望能夠將它們保存在共享文件夾(服務器,不同的PC或Mac,Nas等)上。 )。在服務器上沒有數據庫的共享網絡上的數據應用程序體系結構

部署會像這樣:第一臺PC上

  • 安裝,我們選擇一個網絡驅動器,共享,任何創造的所有文件在此位置的應用程序。
  • 在我們安裝的應用程序,我們選擇了相同的位置(在網絡上)的第二臺PC,應用程序不會產生任何東西,它認爲它已經存在,它使用這些文件作爲應用程序的數據
  • 同在其他客戶端上的東西

應用程序的文件將成爲文檔(最有可能的XML格式的文檔),當打開應用程序時,我們要顯示所有現有的文檔。問題是,我們不僅希望獲得文檔列表並能夠編輯它們的內容,還希望能夠編輯文檔的屬性,所以我們想要一個文件(Sqlite, XML,無論什麼)表示所有文檔及其屬性的列表。地址列表同樣的東西。

我知道所有與數據庫解決方案完全一樣的客戶端/服務器,但這種解決方案是不可能的。我首先在查看數據文件的SQLite,但我知道併發性可能是一個真正的問題,並且文件鎖定效果不佳。問題是,我會遇到與簡單的XML文件相同的問題(在多個用戶正在工作時刷新內容,訪問鎖定的文件)。

所以我想我最後的問題是:它是否可行?有沒有其他方法可以讓我們更輕鬆地做到這一點?

編輯:

好的,我不迴應每一個崗位或評論,因爲我目前使用SQLite測試併發。我做了什麼,如果我測試這種方式是錯誤的,請糾正我,是啓動X BackgroundWorker,它們都將在示例數據庫中插入記錄(每次啓動應用程序時都會重新創建)。我嘗試通過這些背景工作者在數據庫中啓動100次INSERT迭代。

當然,併發性正在運行一個應用程序,它只是等待最後一個BackgroundWorker完成它的工作,然後寫下一個記錄。我也嘗試在幾乎同一時間插入,這意味着我在每個等待模5時間戳(每5秒鐘,每個BackgroundWorker運行)的BackgroundWorker中放置一個循環。再次,它正在等待上一個插入查詢在下一個之前結束,一切工作正常。我甚至用500個BackgroundWorkers試了一下,效果很好。

然後我嘗試多次啓動我的應用程序並同時運行它們。當我這樣做時,確實有一些問題。有兩個我的應用程序的實例仍然正常工作,但是當它用4-5個實例進行嘗試時,它確實有問題,並且出現了兩種類型的錯誤:1.數據庫被鎖定2.磁盤I/O故障。但是大多數鎖定的數據庫。

我做的事情非常密集,在我的應用程序的場景中,它永遠不會遇到5個進程,試圖同時插入500個hunded行(也許我會得到兩個或三個連接的併發)。但是真正困擾我的是什麼讓我認爲我的測試方法不是一個好的方法,那就是我遇到了這些錯誤,試圖在共享網絡上,NAS上以及我自己的硬盤上工作。每次它可能爲30-40查詢工作,然後扔我「數據庫被鎖定」的錯誤。

我測試它錯了嗎?也許我不應該這麼努力地完成這項工作,但我仍然不相信SQLite不是我想要做的很好的選擇,因爲併發將會非常小。

+0

爲什麼你不能使用數據庫服務器? – Maarten 2014-10-28 09:55:38

+0

從你的問題來看,似乎你想對原始XML文件有類似數據庫的數據訪問。你能解釋爲什麼一個數據庫是不可能的嗎?我只能猜測,但你知道你可以將XML文件存儲在數據庫中嗎? – DMAN 2014-10-28 09:55:40

+0

我們針對的是非常小的客戶(大部分時間沒有服務器,只有外部硬盤或Nas),我們希望能夠在一臺PC上使用該應用程序或在多臺PC上共享數據,但項目不包括開發服務器版本。我們也想提出一個完整的試用版本,這並不適合客戶/服務器解決方案。最後一件事:我們與客戶端/服務器應用程序建立了合作伙伴關係,我們每天都會在這些架構中看到許多問題(訪問權限,防火牆等)。我們不希望這樣。 – 2014-10-28 10:07:52

回答

1

你說得對,Sqlite在數據庫文件上使用文件鎖,所以將所有數據文件存儲到數據庫中會帶來編寫文檔的寫缺陷問題。

可能是您在特定文件級別實現簡單樂觀/悲觀鎖定的更好選擇?例如,如果使用悲觀鎖定,則不允許任何人編輯特定文件,如果有人正在編輯它。在這種情況下,您只會鎖定一個文件,而不是鎖定整個數據庫。如果衝突的可能性(同時編輯特定文件)相當低,最好是樂觀鎖定。

簡單的樂觀鎖定實現:

當用戶獲取閱讀文件 - 沒關係,這裏沒有問題。如果用戶獲取文件進行編輯,您可以計算該文件的散列(或獲取文件上次更新時間的時間戳),然後當用戶嘗試保存編輯文件時,比較當前(保存時)散列/時間戳以確保該文件沒有被其他人更改。如果文件沒有被更改,那麼可以保存它。 IF文件已被更改,則當前用戶運氣不佳,您需要通知他。當這種「不幸」的可能性非常低時,這種樂觀的情況很不錯。否則,最好堅持悲觀鎖定,當你不允許用戶開始文件編輯時,如果有人正在做這件事。

+0

在「單個文件」的基礎上,我明白你的意思,我認爲這是要走的路。儘管如此,我仍然必須允許讀取鎖定文件。但我不知道在網絡共享上實現文件鎖定是否容易......但是關於我的文檔「列表」,我仍然可以使用Sqlite,但在自己的應用程序中實現一層鎖定嗎?用戶可以隨時閱讀列表,如果他試圖編輯它,它會檢查它是否被鎖定,如果不是,它會檢查用戶是否未改變其他用戶所做的更改(並在以下情況下警告用戶),如果沒有問題鎖定文件,寫入並解鎖。好像? – 2014-10-28 13:11:00

+0

如果我正確理解你,你正在談論樂觀鎖定情況,我剛剛更新了答案。而且,是的,我認爲您可以使用Sqlite不僅用於存儲「文件列表」,還可用於存儲有關文件鎖定的信息,文件最後更新時間等,以管理併發修改。 – ialekseev 2014-10-28 13:59:40

1

隨着你的樂觀/悲觀鎖定,你最終試圖建立一個數據庫。另外,在嘗試保持多個文件彼此同步時,您會遇到一致性問題。考慮是否更新「元數據」文件,並且由於網絡信號而導致寫入中途失敗。隨後會發生文件損壞,並且您將繼續嘗試從備份中重新構建。

我建議幾個可能的解決方案:

1)主機的內容自己,並讓他們成爲純粹的客戶端(基於雲的部署是非常理想的)。大多數網絡/防火牆問題可以通過使用HTTP作爲傳輸(Web服務)來繞過。 2)有一個工作站是「服務器」,它將數據文件保存在NFS上。這將爲您提供事務完整性,增量備份等。有良好的嵌入式數據庫管理系統批次可幫助您管理這種複雜性。 MS SQL Server甚至有一些很好的選擇。

+0

感謝您的回答,我的一部分對此SQLite解決方案只想說「不」。我聽到你在說什麼,但我仍然試着儘可能最好地測試SQLite,看看它是否可以工作(你可以看到我編輯了我的第一篇文章) – 2014-10-30 10:09:47

+0

但是關於你的兩個解決方案,我會非常樂意使用第一個,但我們知道我們的客戶和他們的隱私,說服他們把他們的數據放在局域網之外的服務器上可能很困難。對於你的第二個解決方案,你會說我仍然在做一個clienz/server應用程序,只保存Nas上的數據文件(而不是數據庫),例如? – 2014-10-30 10:21:12

+1

這似乎是一個非常合理的解決方案。順便說一句,我發現後,快速谷歌搜索:http://beets.radbox.org/blog/sqlite-nightmare.html似乎很可能你有與SQLLite相同的問題,它看起來像它可以通過重新編譯用一個標誌來啓用毫秒超時... – 2014-10-30 13:11:15

相關問題