接手一個專案,資料庫里面使用GUID做主鍵的,這個GUID是WCF里面代碼生成的,但有時會重復。
foreach (var itemRow in orderDT)
{
if (itemRow.RowState == DataRowState.Added)
{
itemRow.OrderID = Guid.NewGuid();
itemRow.EndEdit();
}
}
網上找的解決方案:讓資料庫自動生成。但我看了下專案,還有其他的也要修改,不想加班。
想問下大牛們有其它辦法沒?
uj5u.com熱心網友回復:
有時會重復。。。聽起來你重復的次數還不少啊?
可是guid重復的概率應該非常非常小才對。
是不是代碼問題啊?
uj5u.com熱心網友回復:
正常應該是運行一兩個月才有個幾次重復,你在保存加個try catch,通過資料庫的唯一性約束保證不會入庫重復uj5u.com熱心網友回復:
代碼里面加了 try catch 就是現在重復有高,過上幾天就重復了,每次都會提示需要重新保存,
不知道這個寫法是不是有問題。
foreach (var itemRow in orderDT)
{
if (itemRow.RowState == DataRowState.Added)
{
//WCF端生成下Guid
itemRow.OrderID = Guid.NewGuid();
itemRow.EndEdit();
}
}
//更新到資料庫
OrderTableAdapter orderTableAdapter = new OrderTableAdapter();
orderTableAdapter.Update(orderDT);
uj5u.com熱心網友回復:
概率很小的,訂單id看能不能改成時間+guiduj5u.com熱心網友回復:
var list1 = new List<info>();
info info1=new info();
for (int i = 0; i < 3; i++)
{
list1.Add(info1);
}
foreach (var item in list1)
{
item.department = Guid.NewGuid().ToString();
}
這種情況下賦值item.department 值的guid都一樣,你查一下賦值代碼是否有類似代碼
uj5u.com熱心網友回復:
如果是重復了可以去資料查詢一下,如果已經存在,就重新生成吧uj5u.com熱心網友回復:
應該是100年內基本上不會重復(即使是同一臺機器上)。仔細除錯、測驗你的程式吧。uj5u.com熱心網友回復:
“OrderID重復”的是新增的記錄,還是修改的記錄?
uj5u.com熱心網友回復:
你需要測驗,然后除錯重復的記錄(在 OrderTableAdapter orderTableAdapter = new OrderTableAdapter() 這條陳述句之前),根據重復的 OrderID 來反推之前的賦值邏輯錯誤。.net 這方面不會有什么錯誤,應該檢查自己的程式邏輯錯誤。
uj5u.com熱心網友回復:
沒看懂你要干嘛既然是主鍵,就不能有一點點重復
而且guid怎么會重復
uj5u.com熱心網友回復:
看看這個,有序guidhttps://www.cnblogs.com/slyzly/articles/9215629.html
uj5u.com熱心網友回復:
guid在單機情況下如果你是正確獲取,同一個毫秒1000條以內是不會重復的。所以遇到重復的問題請先檢查自己的代碼生產部分。
uj5u.com熱心網友回復:
你應該自己寫測驗,然后除錯,跟資料庫無關,來找到你的 c# 代碼在呼叫 DbAdapter.Update 陳述句之前的 OrderID 的所謂 bug。如果是盲目糾結什么“網上找的解決方案:讓資料庫自動生成”,那么其實是相當盲目的,對開發程序掌握的不仔細。你應該親自找到 c# 代碼的 bug,知道哪一條陳述句具體地體現了 .net framework 有 bug,并且去微軟領取10萬獎金,這才是程式員該做的,而且只需要花10分鐘時間,找到 bug (而不是隨便改變)不至于說什么“不想加班”。uj5u.com熱心網友回復:
重復率這么高?我看有不少網站系統,都是用guid做主鍵的。
uj5u.com熱心網友回復:
這段代碼是在同一個機器上運行的嗎?還是…在網路內的不同機器上運行的。
問題雖然有點low,但還是問一問
uj5u.com熱心網友回復:
我是說本樓的問題有點low
還不能編輯回復?洗掉也不行?
uj5u.com熱心網友回復:
.net framework有1個bug,我發現的,100%是bug
uj5u.com熱心網友回復:
guid生成是于網卡mac和時間戳有關,所以在你的回圈里面加入sleep 試試
uj5u.com熱心網友回復:
那么……沒有回報給微軟嗎?
uj5u.com熱心網友回復:
確實不太可能重復,你打一下日志吧,例如:var list1 = new List<info>();
info info1=new info();
for (int i = 0; i < 3; i++)
{
list1.Add(info1);
}
foreach (var item in list1)
{
item.department = Guid.NewGuid().ToString();
LoggerHelper.Write("生成 的id:" + ToJson(item)); }
//更新到資料庫
OrderTableAdapter orderTableAdapter = new OrderTableAdapter();
LoggerHelper.Write("更新的資料:" + ToJson(orderDT));
orderTableAdapter.Update(orderDT);
在碰到重復時,看看日志
uj5u.com熱心網友回復:
就我個人感覺,你很容易出現重復guid應該是代碼導致的。具體原因,你只能自己分析代碼和資料。
如果你能力有限,就讓領導來看,自己多測驗為主。
uj5u.com熱心網友回復:
先生成一批(可在后面累加編號),放到集合中慢慢使用,用完了在生成一批。單個服務可保證絕對唯一。多個服務可加標識區分uj5u.com熱心網友回復:
檢查代碼邏輯吧,GUID不會重復的uj5u.com熱心網友回復:
GUID 不是根據網卡上面的一個唯一標識 生成的嘛。。uj5u.com熱心網友回復:
沒遇到過,這得多小的概率,最簡單的做法是如果不在乎長度,生成兩個拼一起uj5u.com熱心網友回復:
但感覺是代碼問題uj5u.com熱心網友回復:
update 為啥要new 一個guid 沒懂。
有時會重復。。。
聽起來你重復的次數還不少啊?
可是guid重復的概率應該非常非常小才對。
是不是代碼問題啊?
代碼里面加了 try catch 就是現在重復有高,過上幾天就重復了,每次都會提示需要重新保存,
不知道這個寫法是不是有問題。
foreach (var itemRow in orderDT)
{
if (itemRow.RowState == DataRowState.Added)
{
//WCF端生成下Guid
itemRow.OrderID = Guid.NewGuid();
itemRow.EndEdit();
}
}
//更新到資料庫
OrderTableAdapter orderTableAdapter = new OrderTableAdapter();
orderTableAdapter.Update(orderDT);
uj5u.com熱心網友回復:
用幾年了,沒遇到過重復的,我用的C# guid.newgudid()uj5u.com熱心網友回復:
日媽,我笑了好吧? guid還能重復的,別逗我,真的!你信不過GUID,你就每次去資料庫校驗一次撒,重復了就自己生成一個uj5u.com熱心網友回復:
樓主一本正經的 得出結論:GUID重復了,導致了BUG頓時搞得我 三觀崩坍:太可怕了,我過去幾年寫得好幾個大系統 都得完蛋的節奏 ~
uj5u.com熱心網友回復:
生成一個ID后讓程式暫停1毫秒,再繼續生成。uj5u.com熱心網友回復:
額,這么久了,樓主還沒有解決這個問題么uj5u.com熱心網友回復:
.net 框架的 guid 演算法不保證不重復,但是可能性極低,應該是用現在普通家用 pc 則百年難遇。“暫停1毫秒”這并不是針對guid機制,在同一毫秒產生多個 guid 值并沒有問題。我倒是覺得,許多時候有人說“要刻意延遲”實際上是一種技術上的bug。就好象有的人寫不出來穩定可靠的高性能低消耗的通訊代碼,就寄希望于胡亂插入 Sleep 代碼來一卡一卡地減少問題,這種做法不好。
uj5u.com熱心網友回復:
guid是uuid的微軟實作。UUID是指在一臺機器上生成的數字,它保證對在同一時空中的所有機器都是唯一的。通常平臺會提供生成的API。按照開放軟體基金會(OSF)制定的標準計算,用到了以太網卡地址、納秒級時間、芯片ID碼和亂數。
UUID由以下幾部分的組合:
(1)當前日期和時間,UUID的第一個部分與時間有關,如果你在生成一個UUID之后,過幾秒又生成一個UUID,則第一個部分不同,其余相同。
(2)時鐘序列。
(3)全域唯一的IEEE機器識別號,如果有網卡,從網卡MAC地址獲得,沒有網卡以其他方式獲得。
UUID的唯一缺陷在于生成的結果串會比較長。關于UUID這個標準使用最普遍的是微軟的GUID(Globals Unique Identifiers)。在ColdFusion中可以用CreateUUID()函式很簡單地生成UUID,其格式為:xxxxxxxx-xxxx- xxxx-xxxxxxxxxxxxxxxx(8-4-4-16),其中每個 x 是 0-9 或 a-f 范圍內的一個十六進制的數字。而標準的UUID格式為:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12),可以從cflib 下載CreateGUID() UDF進行轉換。
uj5u.com熱心網友回復:
嚇得我用了很低端的方法檢測中…………
uj5u.com熱心網友回復:
從沒遇見過GUID重復問題,還是找找代碼本身問題吧uj5u.com熱心網友回復:
不會重復吧,沒有遇過uj5u.com熱心網友回復:
我記得老師講過這個東東就是毫秒級的,上面他用的是無節制的回圈,有可能1毫秒會產出會多個,所以會有重復,所以,如果他不改變方式,還是這樣的方式,暫停1毫秒是有必要的。uj5u.com熱心網友回復:
一定是自己代碼的問題,.Net即使有 bug也不會這么低級,Guid 是基于高精度計時器(100ns級)以及硬體ID等計算出來的,在同一臺計硬體上不可能重復。uj5u.com熱心網友回復:
理論上不會重復。uj5u.com熱心網友回復:
重復是個不可能事件, 概率非常非常小uj5u.com熱心網友回復:
我記得老師講過這個東東就是毫秒級的,上面他用的是無節制的回圈,有可能1毫秒會產出會多個,所以會有重復,所以,如果他不改變方式,還是這樣的方式,暫停1毫秒是有必要的。
納秒,不是毫秒
uj5u.com熱心網友回復:
var list1 = new List<info>();
info info1=new info();
for (int i = 0; i < 3; i++)
{
list1.Add(info1);
}
foreach (var item in list1)
{
item.department = Guid.NewGuid().ToString();
}
這種情況下賦值item.department 值的guid都一樣,你查一下賦值代碼是否有類似代碼
你這個問題是因為list1里邊放了3個info1物件,這3個info1,其實是一個物件,info1= new Info() 放到for回圈里邊就行了
uj5u.com熱心網友回復:
樓主也可以參考下上邊的問題,不出意外的話,有生之年是看不到GUID真正重復的。uj5u.com熱心網友回復:
同一臺機器單執行緒運行就不會產生重復的GUID,over!uj5u.com熱心網友回復:
同一臺機器火力全開多執行緒同時產生GUID,這個不符合使用GUID的初衷,是有可能引數重復的GUIDuj5u.com熱心網友回復:
找其他地方,GUID重復,這個基本概率為0;uj5u.com熱心網友回復:
我一開始以為這個丟下墳就跑的lz回來了,后來發現你們考古隊在開始分析自己的問題了,不能自己開帖子一定要現場考古嗎?
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/116359.html
標籤:C#
上一篇:TcpClient傳輸接收和發送資料太小,怎么擴大容量
下一篇:寫注冊表出錯了
