流水號(hào)的獲取在單機(jī)版的程序中只需要簡單的遞增就可以解決。但是在分布式系統(tǒng)中存在多個(gè)客戶端同時(shí)請(qǐng)求同一個(gè)流水號(hào)的問題,如果處理不好容易導(dǎo)致多個(gè)客戶端獲得同一個(gè)流水號(hào)。
解決方案一
在Oracle數(shù)據(jù)庫中有專門的序列管理sequence,具體的介紹在網(wǎng)上可以找到很多。但是在實(shí)際使用中存在很多的問題:
1、如果有很多個(gè)不同的序列,并且在需要根據(jù)時(shí)間變化(每天0點(diǎn)重置)時(shí)處理起來很麻煩。
2、隨時(shí)間增加數(shù)據(jù)庫中的序列越來越多。
3、在首次創(chuàng)建一個(gè)序列的時(shí)候需要激活后才能正常使用。
所以果斷放棄了這個(gè)方案。
解決方案二
大體的思路:在數(shù)據(jù)庫中專門建一個(gè)表存儲(chǔ)各類的序列,在服務(wù)器端創(chuàng)建一個(gè)服務(wù)專門提供各類序列當(dāng)前的流水號(hào)。客戶端通過這個(gè)服務(wù)來獲取序列,不能直接去數(shù)據(jù)庫中查
第1步:在數(shù)據(jù)庫中專門創(chuàng)建一個(gè)新的表用來存儲(chǔ)這些序列。表結(jié)構(gòu)如下:
1、FLAG(標(biāo)志碼 主鍵):代表序列的標(biāo)志
2、Sequence(當(dāng)前的流水號(hào)):默認(rèn)為0
3、UpdateTime(更新時(shí)間):根據(jù)自己的需要來創(chuàng)建
第2步:先創(chuàng)建一些接口
1、數(shù)據(jù)服務(wù)的接口
1 public interface IDataOperator 2 { 3 int ExecuteNonQuery(List<string> list); 4 int ExecuteNonQuery(string strSql); 5 int ExecuteNonQuery(List<string> list, ref string strError); 6 int ExecuteNonQuery(string strSql, ref string strError); 7 T ExecuteScalar<T>(string strSql); 8 T ExecuteScalar<T>(string strSql, ref string strError); 9 DataSet GetDataSet(string strSql);10 DataSet GetDataSet(string strSql, ref string strError);11 DataTable GetDataTable(string strSql);12 DataTable GetDataTable(string strSql, ref string strError);13 }View Code
2、流水號(hào)的接口
1 public interface ISequence2 {3 int GetNext(string strFlag);4 }View Code
第3步:在服務(wù)器端創(chuàng)建一個(gè)服務(wù),這個(gè)服務(wù)有兩個(gè)功能。我這邊客戶端和服務(wù)端的通信用的是Remoting技術(shù)。這里就不展示相關(guān)的代碼了。
1、做客戶端的數(shù)據(jù)中轉(zhuǎn),直接和數(shù)據(jù)庫服務(wù)器之間通信,
1 public class SqlServer : MarshalByRefObject,IDataOperator 2 { 3 #region 私有字段 4 PRivate string strConn; 5 #endregion 6 /// <summary> 7 /// 構(gòu)造器 8 /// </summary> 9 public SqlServer () 10 { 11 strConn = string.Format(@"User ID={0};PassWord={1};Data Source={2};Pooling=true;Min Pool Size=0;Max Pool Size={3};", 12 “”, 13 “”, 14 “” 15 “”; 16 17 } 18 /// <summary> 19 /// 打開數(shù)據(jù)庫連接 20 /// </summary> 21 /// <param name="strError">返回錯(cuò)誤信息</param> 22 /// <returns></returns> 23 public bool OpenTest(ref string strError) 24 { 25 bool blResult = false; 26 try 27 { 28 using (SqlConnection conn = new SqlConnection(strConn)) 29 { 30 conn.Open(); 31 conn.Close(); 32 } 33 blResult = true; 34 } 35 catch(Exception ex) 36 { 37 strError = ex.Message; 38 } 39 return blResult; 40 } 41 /// <summary> 42 /// 執(zhí)行一個(gè)SQL語句集合返回操作成功數(shù) 43 /// </summary> 44 /// <param name="strsql"></param> 45 /// <param name="parameter"></param> 46 /// <returns></returns> 47 public int ExecuteNonQuery(List<string> list, ref string strError) 48 { 49 int intResult = 0; 50 int i = 0; 51 if (list.Count > 0) 52 { 53 try 54 { 55 using (SqlConnection conn = new SqlConnection(strConn)) 56 { 57 58 conn.Open(); 59 SqlTransaction tran = conn.BeginTransaction(); 60 61 try 62 { 63 using (SqlCommand cmd = conn.CreateCommand()) 64 { 65 cmd.Transaction = tran; 66 for (i = 0; i < list.Count; i++) 67 { 68 cmd.CommandText = list[i].Trim(); 69 intResult+= cmd.ExecuteNonQuery(); 70 } 71 tran.Commit(); 72 } 73 74 } 75 catch (Exception ex) 76 { 77 try 78 { 79 intResult = -1; 80 tran.Rollback(); 81 82 strError = 83 string.Format("{0}個(gè)操作回滾成功!{1}/r/n ErrSQL:/r/n {2}", 84 i, ex.Message, list[i]); 85 } 86 catch(Exception ex2) 87 { 88 intResult = -2; 89 strError = 90 string.Format("{0}個(gè)操作回滾失敗!{1}/r/n ErrSQL:/r/n {2}", 91 i, ex2.Message, list[i]); 92 } 93 } 94 finally 95 { 96 conn.Close(); 97 } 98 } 99 }100 catch (SqlException ex)101 {102 103 strError = ex.Message;104 }105 106 }107 else108 {109 strError = string.Format("ExecuteNonQuery(List<string> list):未傳入需要執(zhí)行的SQL語句");110 }111 return intResult;112 113 }114 /// <summary>115 /// 執(zhí)行一個(gè)SQL語句集合返回操作成功數(shù)116 /// </summary>117 /// <param name="strsql"></param>118 /// <param name="parameter"></param>119 /// <returns></returns>120 public int ExecuteNonQuery(List<string> list)121 {122 int intResult = 0;123 int i = 0;124 if (list.Count > 0)125 {126 using (SqlConnection conn = new SqlConnection(strConn))127 {128 conn.Open();129 SqlTransaction tran = conn.BeginTransaction();130 using (SqlCommand cmd = conn.CreateCommand())131 {132 try133 {134 cmd.Transaction = tran;135 for (i = 0; i < list.Count; i++)136 {137 cmd.CommandText = list[i].Trim(); 138 intResult += cmd.ExecuteNonQuery();139
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注