在併發資料連線超時問題

2021-09-28 17:27:00 字數 1520 閱讀 8009

最近遇到乙個高併發的問題,當初的需求優惠券券號是按照 日期 datetime.now.tostring("yyyymmddhhmmss")  + 最大訂單號+1 的方式去新增券號的。

由於業務裡面還涉及到多張表操作,用了事務。

第一版上線:  發現 很多訂單號重複,找到原因是因為 在併發量高的時候,從資料庫獲取最大訂單號時會產生併發,最新的單號沒有新增到資料庫,另乙個執行緒已經從資料庫查詢到最大訂單號,這樣兩個訂單號 就是相同的。

為了解決這個問題 ,於是,第二個版本產生。

第二版上線:在獲取單號到 新增資料庫這段**加入了鎖。

**如下:

private static object objlock = new object();

lock (objlock)

這樣跟蹤了一天,發現不會產生重複的訂單號 ,但是過了幾天發現另外乙個更加嚴重的問題:一旦併發量達到一定量的時候,這個方法就越來越慢,從最開始的10幾毫秒,慢慢到幾百毫秒,然後要十幾秒,一百秒,然後服務就直接掛了。並且會影響到其他負載均衡到的幾台伺服器都掛掉。

通過日誌跟**的分析,發現 在新增券的**裡面原先用到了事務。然後在事務裡面又新增了鎖。這是乙個矛盾的地方,這樣直接導致**效能下降的很快。為了解決這個問題,於是再次修改**

第三版上線:

1:為了解決執行緒池超時問題,必須立刻把鎖解除,於是把鎖的那段**注釋。

2:為了解決券號重複的問題,使用隨機數來算,字串+ datetime.now.tostring("yyyymmddhhmmss")+隨機數

random rad = new random();//例項化隨機數產生器rad;

int value = rad.next(1000, 10000);//用rad生成大於等於1000,小於等於9999的隨機數;

這樣獲取隨機數,但是隨機數獲取機制是:

在.net中,隨機數一般是用random來獲取,但是當在多工的並行化程式設計時,問題就出現了。因為random是基於時間作為種子來生成偽隨機數的,而如果程式在多核並行時,在同一時間內的多個核中取到的時間是一樣的,這樣一來,生成的偽隨機數就有可能會有一樣的。如果業務需求中需要不可重複的隨機數,那麼這後果將會相當嚴重

所以不能直接用以上**獲取 隨機數。

所以必須採取一種新的方式來獲取執行緒安全的偽隨機數。

於是用  rngcryptoserviceprovider的加密隨機生成器,再用其中的強隨機序列的方法getbytes來實現隨機。

**如下:   呼叫 getrandomnumber方法 ,引數是隨機數的長度,需要幾位數 引數就是多少。

public static string getrandomnumber(int length)

return strpwd;

}public static int getrandomseed()

總結:這樣修改後,後面就不會再出現重複的優惠券單號。  並且原先高峰期的要幾秒,幾十秒的時間 回落到 100毫秒以內。

MYSQL 連線超時問題

前不久維護了乙個 專案,專案的後台設計是 管理者進入 後台連線,第一步就是建立資料庫,只需按照提示輸入 ip 位址 即在那個ip 位址的主機上建立資料庫 使用者名稱 密碼 埠號 即所在ip 位址的主機上安裝的mysql 的使用者名稱 密碼和埠號 資料庫的名字這5項內容,然後就開始自動建立資料庫,建立...

oracle 遠端連線超時問題

1 檢查你的伺服器oracle監聽是否啟動 lsnrctl status 如果沒有建立監聽或者沒有啟動,遠端是訪問不到的。2 檢查你的客戶端能否連到伺服器1521埠 telnet 伺服器ip 1521 因為有可能區域網內遮蔽了該ip的該埠的鏈結 3 檢查你的客戶端鏈結oracle配置是否正常,看看鏈...

MySQL連線超時關閉問題

其中wait timeout就是負責超時控制的變數,其時間為長度為28800s,就是8個小時,那麼就是說mysql的服務會在操作間隔8小時後斷開,需要再次重連。也有使用者在url中使用jdbc.url jdbc mysql localhost 3306 nd?autoreconnect true來使...