im使用nhibernate作为我的Web服务的orm,并且我已经实现了CustomSqlDriver。我创建CustomSqlDriver的原因是,我需要获取并将在应用程序中执行的每个查询(及其参数值)保存到数据库。 每次发生查询(选择,更新等)时,都会按各自的顺序调用AdjustCommand方法。
public class CustomSqlDriver : SqlClientDriver {
private static readonly log4net.ILog log = log4net.LogManager.GetLogger("CustomSqlClientDriverLogger");
private static readonly Object _lock = new Object();
public override void AdjustCommand(IDbCommand command)
{
base.AdjustCommand(command);
var parameters = (SqlParameterCollection)command.Parameters;
QueryType queryType = GetQueryType(command);
string tableName = GetTableName(command.CommandText);
string fullCommandText = GetFullQuery(command, parameters);
Task.Run(() =>
{
lock (_lock)
{
log.Info($"Trying to save the query = {fullCommandText}");
SaveToDb((int)queryType, fullCommandText, tableName);
}
});
}
}
我需要保存每个查询,以便稍后在不同的FIFO处理中使用它们。 不能在同一线程中执行此操作(因为它可能很慢)。 如您所见,我尝试在Task.Run()中的静态对象上使用锁,并且只要对任何Web方法的调用都是同步的,它就可以工作,但是如果我并行调用它们,则某些行在保存时会丢失顺序到数据库。
我不确定这是否是最好的方法D: 任何帮助将不胜感激。
答案 0 :(得分:2)
某些行保存到数据库后失去顺序。
Task.Run
不保证有关订单的任何内容;项目可以按几乎任何顺序出队,即使它们以正确的顺序出队并安排在不同的线程上,两个线程也可以以不同的顺序进行处理并以不同的顺序到达锁。即使他们以正确的顺序到达锁定,我也不认为严格保证在所有情况下(more reading here)都将保留锁定队列顺序-仅一个就会有锁。
如果您需要FIFO:您需要定义该FIFO是:某种东西进入可靠的同步队列或列表或类似列表的顺序。事后您不能添加FIFO。