Hallo,Linq to SQL并发问题
我有可以调用多个方法的web服务。每次调用其中一种方法时,我都会将调用记录到统计数据库中,以便我们知道每个方法每个月调用多少次以及平均处理时间。
每次我登录统计数据时,首先检查数据库以查看当前月份的方法是否已经存在,如果不存在,则创建并添加该行。如果它已经存在,我将需要的列更新到数据库。
我的问题是,有时当我更新一行时,我得到“行未找到或更改”异常,是的,我知道这是因为该行已被修改,因为我读它。
为了解决这个问题我已经尝试使用没有成功如下:使用在我的DataContext
- 使用。
- 在TransactionScope中使用。
- 使用互斥量,这是行不通的,因为Web服务是(不确定我称之为正确的想法)复制出来在不同的PC上的性能,但仍然使用相同的数据库。
- 解决异常中的并发冲突,这不起作用,因为我需要获取新的数据库值并为其添加值。
下面我添加了用于记录统计数据的代码。任何帮助将非常感激。
public class StatisticsGateway : IStatisticsGateway
{
#region member variables
private StatisticsDataContext db;
#endregion
#region Singleton
[ThreadStatic]
private static IStatisticsGateway instance;
[ThreadStatic]
private static DateTime lastEntryTime = DateTime.MinValue;
public static IStatisticsGateway Instance
{
get
{
if (!lastEntryTime.Equals(OperationState.EntryTime) || instance == null)
{
instance = new StatisticsGateway();
lastEntryTime = OperationState.EntryTime;
}
return instance;
}
}
#endregion
#region constructor/initialize
private StatisticsGateway()
{
var configurationAppSettings = new System.Configuration.AppSettingsReader();
var connectionString = ((string)(configurationAppSettings.GetValue("sqlConnection1.ConnectionString", typeof(string))));
db = new StatisticsDataContext(connectionString);
}
#endregion
#region IStatisticsGateway members
public void AddStatisticRecord(StatisticRecord record)
{
using (db)
{
var existing = db.Statistics.SingleOrDefault(p => p.MethodName == record.MethodName &&
p.CountryID == record.CountryID &&
p.TokenType == record.TokenType &&
p.Year == record.Year &&
p.Month == record.Month);
if (existing == null)
{
//Add new row
this.AddNewRecord(record);
return;
}
//Update
existing.Count += record.Count;
existing.TotalTimeValue += record.TotalTimeValue;
db.SubmitChanges();
}
}
感谢您的回复。我通过创建一个存储过程来解决问题!像魅力一样工作 – Michael 2010-09-29 12:34:35
非常棒!只是好奇,你在存储过程中是否打扰了sp_getapplock? (因为只是将逻辑移动到存储过程将大大降低并发问题的机会。) – shaunmartin 2010-09-29 15:14:55
我使用了HOLDLOCK和ROWLOCK,请检查我的答案。 – Michael 2010-09-30 10:56:36