none
關於 xADO.conn = New SqlConnection(connDbStr) RRS feed

  • 問題

  • 請教各位大大::

    那個      xADO.conn = New SqlConnection(connDbStr)  小弟我用此方式連接資料庫


    那我想說 用 Thread 用約 100個  去作

           .cmd = New SqlCommand(InsertCmd, .conn)

    請教 這樣是否可行 會不會有數量上的限制 或者說根本不能這樣作呢

    謝謝您
    2009年7月22日 下午 03:35

解答

  • A與B是否要分成兩隻程式沒有絕對,只要能夠區隔即可
    A與B分開是正確的,這樣才吻合物件導向中的單一職責設計.

    所以你可以將你的程式改成A讀取資料->寫入MSMQ , B由MSMQ讀取資料存入資料庫.
    而C就是MSMQ的訊息.其實改變並不大.

    另外一個用MSMQ的原因就是確保你的程式可用性,在你的需求中很明顯的資料來源非常多,如果不透過類似MSMQ的機制,勢必會導致寫入資料庫時可能會來不及而導致某些資料可能會LOSE.這類問題的做法大多是採用QUEUE處理,方式很多,MSMQ只是現有較簡單的機制.

    • 已標示為解答 Max197 2009年7月28日 上午 06:18
    2009年7月27日 上午 12:25
  • 我的想法是.一般的寫法.也就是不要用Thread,不要用Queue...不管你是直接丟,或者寫一個資料存取層都沒差.
    反正就是處理一個Item就寫回一個Item.
    而就資料庫效能而言.你可以將所有的關聯都去掉.只留一個PK欄位作限制值.
    就網路效能而言,你在資料庫端建SP,然後使用SP傳必要的資料就好了.不要直接使用SqlCommand.這樣會多傳很多指令.
    程式越簡單越直覺越好.你寫很多Thread,Queue...他內部反而多做很多排程...程序.

    • 已標示為解答 Max197 2009年7月28日 上午 06:18
    2009年7月28日 上午 06:06

所有回覆

  • ADO.Net 有Pool功能,預設是10,而Pool的機制是用連線字串做為判斷依據,或是同一連線字串但目前此字串的Connection已有使用則會再產生一個.這是在ADO.Net中的機制.
    而另一個問題則是你資料庫的限制.

    所以你的需求如做以下調整則可行,
    1.修改Connection Pool的最大值.
    2.你的資料庫要能同時承受此量的連結

    不過這不是個好做法,一個應用程式相同連線不應該同時間下達Query.如果真需要大量同時間差入請用Queue方式來排隊達成,可以做一個獨立的執行緒,並配合Queue機制(自己寫或使用MSMQ等現有技術)來達成.
    2009年7月22日 下午 11:30
  • 謝謝 Programlin 

    我先述說我目前的狀況是

    1. MS SQL 2005 Server
    2. 同時(1s~5s內)需要寫入資料庫內  
    3. 同時寫入的資料量約 1000筆 ~ 3000筆
      

    阿您說得 Connection Pool 是指  群組  Update 嗎?? 


    2009年7月23日 上午 04:50
  • 大量資料用 SqlBulkcopy可能比較好.
    請參閱MSDN 文件庫
    [SqlBulkCopy 類別 ]
    [SQL Server 中的大量複製作業 (ADO.NET) ] <==這邊有一堆實作範例的連結


    請關心自己的問題,不要問了就放空;這是對別人與自己的尊重
    2009年7月23日 上午 06:37
  • Bill Chung 您好


    但目前我這邊的資料 1000~3000筆他是放在 Array中

    隨時都在變化  就好筆試  有 3000 個 Address 中每一格 的資料 都是  rnd 產生  

    而我需要把資料同步反應到資料庫內

    這樣有辦法透過 SqlBulkcopy 來處理嗎

    2009年7月23日 上午 07:17
  • 你的意思指你有個Array裡面存放很多資料,然後當資料有異動時就會更新資料庫嗎?
    如果你Array中的資料都是相同Connection那你就可以忽略此問題,因為只要不同時超過10筆以上資料做處理就沒有太大問題,如果超出適當調整一下Connection Pool最大連線數量即可,不過除非你資料異動相當頻繁,不然不太可能發生.
    2009年7月23日 上午 07:39
  • 嗯嗯 

    我目前的資料是 每秒鐘 都在變換

    約 3000筆 左右  阿 連線都是用同一個  Connection  

    但更新的時候  是 3000筆 要作同步異動!!

    所以我才會想說用 Thread 用約 300個  同時 更新看看

    但都對應同一個  Connection
    2009年7月23日 上午 08:16
  • ADO.Net Connection Pool的內部運作後,不論你用多少個Thread只要"同時"不超出Connection Pool的最大值就沒有問題.

    但是還是跟你強調一件事你的這個設計方式不是很好.

    2009年7月23日 上午 10:14
  • 是阿 小弟我也覺得這樣作很不好

    >>>>>  一個應用程式相同連線不應該同時間下達Query.如果真需要大量同時間差入請用Queue方式來排隊達成,可以做一個獨立的執行緒,並配合Queue機制(自己寫或使用MSMQ等現有技術)來達成.

    但 您說得這個方法 我尚無好得想法去實現他 說!!

    因為小弟我這個部份是

    擷取外部硬體資料後存到Array內  然後 要同步更新到資料庫

    我想差個  5~10秒應該沒關係 但,怎麼去寫他 實在也是有點困難  像您說得  Queue 我也曾經想過 就用一個執行緒不斷地在跑他

    0~3000

    但後來想想  那用兩個或兩個以上的 Thread 會不會比較快呢??


    另您提到的訊息佇列  用於這樣的狀況  我該往哪方面去想呢??? 

    謝謝 您 ︿︿
    2009年7月23日 下午 01:00
  • 你的想法是正確的

    大致上使用MSMQ這個需求並不難達成
    你只要寫兩隻程式
    1.截取外部硬體資料程式 -> 將資料放到MSMQ
    2.MSMQ -> 寫入資料庫程式

    第2隻程式如果單筆覺得速度不夠可以產生多個thread來負責最多可同時寫入筆數.

    至於MSMQ因為.Net已有支援,使用上很簡單,上Google找一下文件就應該清楚了.
    2009年7月24日 上午 12:04
  • 1.要同步又有MSMQ,你們不會覺得互相矛盾嗎?MSMQ這總序是一次一筆的處理,就不可能實現同步.
    2.與資料庫連結,就不可寫同步程式,其中一定有誤差,因妳主機,設定,網路...而不同.
    3.資料庫有同時寫入數量的限制.Thread也有最大量的限制...所以也不太可能.
    4.如果你怕ConnectionPool限制.你就寫一支資料存取的靜態Class.不用每個地方用到就New一次.然後所有程式將資料丟給他,由他去協調與資料庫的互動.
    2009年7月24日 上午 01:03
  • 好說  您好:

       小弟目前是這樣的  我先夠過網路的方式取得資料後 放到一個 C_Class 的陣列 並依資料類型宣告成不同變數來存放

    Class  C_Class
        Public Structure TagStructure
            '點序號
            Public TagIndex As UInt32
            '點的種類
            Public TagType As Byte
        End Structure
    End Class

        然後 A_Class 僅寫入  C_Class 內的資料 (此部份透過 500~1000個 Thread 來寫入)

        而 我需要另外把  C_Class 內的資料轉入資料庫內  但因為我想說 不要讓 A_Class 同時讀資料又要寫入資料庫 因此 創另外一個 B_Class (僅讀取) 來獨立作這件事情

        但 因為更新速度的關係 所以 我希望可以透過較多的 Thread 用同一個 Connection 來非同步但卻可以較為即時的把 C_Class 內的資料更新到資料庫(SQL Server 2005)內

    我這樣的想法 跟programlin大大說明的 MSMQ 一樣 變成 我需要把 B_Class 作成 MSMQ  只是 我目前  A_Class B_Class C_Class 都在同一支程式內

    我也在想要分成兩支程式 才不會影響到 A_Class 取值的速度 因為他除了取值外還要作另一件事情所以
    希望B_Class不要影響到他

    您覺得我這樣的想法對嗎??   麻煩您了
    2009年7月24日 下午 12:44
  • A與B是否要分成兩隻程式沒有絕對,只要能夠區隔即可
    A與B分開是正確的,這樣才吻合物件導向中的單一職責設計.

    所以你可以將你的程式改成A讀取資料->寫入MSMQ , B由MSMQ讀取資料存入資料庫.
    而C就是MSMQ的訊息.其實改變並不大.

    另外一個用MSMQ的原因就是確保你的程式可用性,在你的需求中很明顯的資料來源非常多,如果不透過類似MSMQ的機制,勢必會導致寫入資料庫時可能會來不及而導致某些資料可能會LOSE.這類問題的做法大多是採用QUEUE處理,方式很多,MSMQ只是現有較簡單的機制.

    • 已標示為解答 Max197 2009年7月28日 上午 06:18
    2009年7月27日 上午 12:25
  • 你整個架構考慮的太複雜了,但我覺得你沒有找到問題點.
    整個架構影響同步的關鍵在:
    1.網路頻寬.
    2.資料庫的磁碟存取.
    上面這二個不解.你程式在多Thread都是浪費.

    2009年7月27日 上午 02:46
  • 嗯嗯


    因為這樣的架構寫起來 對我這個初學者來說也是很困難  不過目前大致已經完成

    但就如  好說 大大說的  

    1.網路頻寬 這個倒是 還ok  目前的狀態是  資料已經都在 Array 內了 (透過 A_Class 取得放入 C_Class內)

    2.資料庫的磁碟存取 <<<  這個部份是小弟我不懂得地方  我該如何 作Array 與 資料庫間 同步異動呢??/

    阿 上面的方法是目前我想的到呢   能否請 好說大大給予提示 與方向 讓我可以思考與實做呢??

    目前的條件如下::  目標作法 目前不用考慮資料來源部份(以處理), 考慮如何將資料轉入資料庫內

    1. 資料約 1000~3000筆  已經存在 Array (透過 A_Class 取得放入 C_Class內)
    2. 已有 SQL 2005 Server 資料庫

    能否請 好說大大  提供您的看法  麻煩您囉  oO_Oo


    2009年7月27日 上午 04:35
  • 我的想法是,所有要同步的瓶頸是在頻寬跟磁碟存取的IO.
    不管你資料結構是Array或其他.基本上存取的速度都比這二項快很多很多.
    所以你有沒有去做Thread其實是沒差的.
    網路,跟磁碟IO通常跟程涉沒太大的關聯.網路頻寬要由網管去設.磁碟IO速度要由資料庫管理師去設如磁碟陣列..

    2009年7月27日 上午 05:12
  • 嗯嗯 我瞭解大大地意思了

    那如果說 現在把小弟的問題單純化   今天兩者  無論網路或者 磁碟 IO 都速度都一致

    那 我很單純的想做這樣的功能 您有什麼建議呢??  先拋開 基底效能的部份 

    我該如何提高自身程序的效能作法哩   


    您的看法 是否如同programlin 大大地想法呢??

    麻煩您囉 感恩 :D
    2009年7月28日 上午 05:49
  • 我的想法是.一般的寫法.也就是不要用Thread,不要用Queue...不管你是直接丟,或者寫一個資料存取層都沒差.
    反正就是處理一個Item就寫回一個Item.
    而就資料庫效能而言.你可以將所有的關聯都去掉.只留一個PK欄位作限制值.
    就網路效能而言,你在資料庫端建SP,然後使用SP傳必要的資料就好了.不要直接使用SqlCommand.這樣會多傳很多指令.
    程式越簡單越直覺越好.你寫很多Thread,Queue...他內部反而多做很多排程...程序.

    • 已標示為解答 Max197 2009年7月28日 上午 06:18
    2009年7月28日 上午 06:06
  • 哈哈 是阿

    小弟 運用起來 也是這樣的狀況 

    本來想說透過 ThreadPool  來作 Thread 管理

            '宣告執行緒 對應的 Class 
            Private myThread() As JobThread    '在 .NET 2.0 SP1 之前,每個 CPU 或每個核心(Core)預設 ThreadPool 的同時執行緒上限是 25 個 Threads,但在 .NET 2.0 SP1 以後 調整到 250 個 Threads
            Private myCallBack As WaitCallback '表示執行緒集區執行緒執行的回呼方法。


    可是 反而用 單一執行緒還快更多  因為我不太會掌握  Threadpool 他產生的執行續數量  呵呵

    這樣我瞭解您的意思了  謝謝您 ^^
    2009年7月28日 上午 06:18