में समवर्ती संघर्ष को हल करने के लिए कैसे करें: एक परिदृश्य: किसी तालिका में डालने के लिए एक निश्चित मात्रा में डेटा डालने के लिए, जब कोई थ्रेसहोल्ड तक नहीं पहुंचता है, तो मैंने इस परिदृश्य को बहु-थ्रेडेड (उदाहरण के लिए एएसपीनेट) समवर्ती समस्याएं दिखाई दीं।ado.net
मेरा प्रश्न समवर्ती समस्या का हल करने के लिए कैसे, lock
मामले का उपयोग नहीं करते
void Main()
{
Enumerable.Range(0,20).ToList().ForEach(i=>{
MockMulit();
});
}
//Start a certain number of threads for concurrent simulation
void MockMulit()
{
int threadCount=100;
ClearData();//delete all data for test
var tasks=new List<Task>(threadCount);
Enumerable.Range(1,threadCount).ToList().ForEach(i=>{
var j=i;
tasks.Add(Task.Factory.StartNew(()=>T3(string.Format("Thread{0}-{1}",Thread.CurrentThread.ManagedThreadId,j))));
});
Task.WaitAll(tasks.ToArray());
CountData().Dump();//show that the result
}
विधि से एक है - संगामिति बहुत गंभीर
void T1(string name)
{
using(var conn=GetOpendConn())
{
var count=conn.Query<int>(@"select count(*) from dbo.Down").Single();
if(count<20)
{
conn.Execute(@"insert into dbo.Down (UserName) values (@UserName)",new{UserName=name});
}
}
}
विधि दो - एसक्यूएल एक साथ रखा कम कर सकते हैं समवर्ती, लेकिन अभी भी मौजूद है
void T2(string name)
{
using(var conn=GetOpendConn())
{
conn.Execute(@"
if((select count(*) from dbo.Down)<20)
begin
--WAITFOR DELAY '00:00:00.100';
insert into dbo.Down (UserName) values (@UserName)
end",new{UserName=name});
}
}
विधि तीन - लॉक डी के साथ समवर्ती estroy, लेकिन मुझे नहीं लगता कि यह एक सबसे अच्छा समाधान है
private static readonly object countLock=new object();
void T3(string name)
{
lock(countLock)
{
using(var conn=GetOpendConn())
{
var count=conn.Query<int>(@"select count(*) from dbo.Down").Single();
if(count<20)
conn.Execute(@"insert into dbo.Down (UserName) values (@UserName)",new{UserName=name});
}
}
}
अन्य मदद विधि
//delete all data
void ClearData()
{
using(var conn=GetOpendConn())
{
conn.Execute(@"delete from dbo.Down");
}
}
//get count
int CountData()
{
using(var conn=GetOpendConn())
{
return conn.Query<int>(@"select count(*) from dbo.Down").Single();
}
}
//get the opened connection
DbConnection GetOpendConn()
{
var conn=new SqlConnection(@"Data Source=.;Integrated Security=SSPI;Initial Catalog=TestDemo;");
if(conn.State!=ConnectionState.Open)
conn.Open();
return conn;
}
आप किस प्रकार का डेटाबेस उपयोग कर रहे हैं जो सम्मिलित डेटा को संभाल नहीं सकता है? – Jake1164
जिस परिदृश्य के खिलाफ आप रक्षा करने की कोशिश कर रहे हैं वह बहुत अस्पष्ट है। क्या आप शायद जो कुछ करने की कोशिश कर रहे हैं उसे फिर से बदल सकते हैं? –
@MarcGravell वास्तव में मैं अपनी ई-कॉमर्स वेबसाइट के लिए एक सामान स्पाइक गतिविधि तैयार कर रहा था। उदाहरण के लिए, केवल 20 सामान ही खरीद सकते हैं, क्योंकि एएसपीनेट बहु-धागा है, हमारे डेटाबेस में 21 रिकॉर्ड दिखाई देते हैं! :( – JeffZhnn