Kịch bản như vậy: một lượng dữ liệu nhất định được chèn vào bảng, khi đạt đến ngưỡng không còn chèn nữa, tôi mô phỏng trường hợp này, trong trường hợp đa luồng (ví dụ asp.net) xuất hiện các vấn đề đồng thời.Cách giải quyết xung đột đồng thời trong ado.net
Câu hỏi của tôi là làm thế nào để giải quyết các vấn đề đồng thời, không sử dụng các trường hợp 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
}
một phương pháp - đồng thời rất nghiêm trọng
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});
}
}
}
phương pháp hai - đặt sql cùng nhau có thể giảm đồng thời, nhưng vẫn tồn tại
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});
}
}
phương pháp ba - với khóa d estroy sự đồng thời, nhưng tôi không nghĩ rằng đó là một giải pháp tốt nhất
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});
}
}
}
phương pháp giúp đỡ khác
//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;
}
Bạn đang sử dụng loại cơ sở dữ liệu nào không thể xử lý dữ liệu chèn? – Jake1164
Kịch bản bạn đang cố gắng bảo vệ chống lại là rất không rõ ràng. Bạn có thể nói lại những gì bạn đang cố gắng làm không? –
@MarcGravell Trên thực tế tôi đã thiết kế một hoạt động tăng đột biến hàng hóa cho ví dụ website.For thương mại điện tử của chúng tôi, một Hàng hóa chỉ có 20 có thể mua, bởi vì asp.net là đa luồng, 21 hồ sơ xuất hiện trong cơ sở dữ liệu của chúng tôi! :( – JeffZhnn