Sql server 在实体框架进行更改之前暂停Azure功能
我有一个Azure功能(Iot集线器触发器):Sql server 在实体框架进行更改之前暂停Azure功能,sql-server,azure,entity-framework-core,azure-functions,azure-iot-hub,Sql Server,Azure,Entity Framework Core,Azure Functions,Azure Iot Hub,我有一个Azure功能(Iot集线器触发器): 选择按时间降序排列的前1条记录 与新记录相比 仅当未来记录与所选记录不同(某些字段不同)时才写入该记录 当记录很快进入azure功能时,问题就出现了——我最终在数据库中发现了重复的记录。我猜这是因为SQL Server没有足够的时间在下一条记录出现和Azure函数选择时在数据库中进行更改,而当Azure函数选择最新记录时,它实际上接收到一条过期记录 我使用EF Core。我确实认为功能没有问题,但您描述的操作的事务性质有问题。为了简单地解决您的问题
我使用EF Core。我确实认为功能没有问题,但您描述的操作的事务性质有问题。为了简单地解决您的问题,您可以尝试使用具有最高隔离级别的事务:
using (var transaction = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions
{
// With this isolation level all data modifications are sequential
IsolationLevel = IsolationLevel.Serializable
}))
{
using (var connection = new SqlConnection("YOUR CONNECTION"))
{
connection.Open();
try
{
// Run raw ADO.NET command in the transaction
var command = connection.CreateCommand();
// Your reading query (just for example sake)
command.CommandText = "SELECT TOP 1 FROM dbo.Whatever";
var result = command.ExecuteScalar();
// Run an EF Core command in the transaction
var options = new DbContextOptionsBuilder<TestContext>()
.UseSqlServer(connection)
.Options;
using (var context = new TestContext(options))
{
context.Items.Add(result);
context.SaveChanges();
}
// Commit transaction if all commands succeed, transaction will auto-rollback
// when disposed if either commands fails
transaction.Complete();
}
catch (System.Exception)
{
// TODO: Handle failure
}
}
}
使用(var事务=新事务范围)(
TransactionScopeOption。必需,
新交易选项
{
//使用此隔离级别,所有数据修改都是顺序的
IsolationLevel=IsolationLevel.Serializable
}))
{
使用(var connection=newsqlconnection(“您的连接”))
{
connection.Open();
尝试
{
//在事务中运行原始ADO.NET命令
var command=connection.CreateCommand();
//你的阅读查询(只是为了举例)
command.CommandText=“从dbo.Whatever中选择顶部1”;
var result=command.ExecuteScalar();
//在事务中运行EF Core命令
var options=new DbContextOptionsBuilder()
.UseSqlServer(连接)
.选择;
使用(var context=newtestcontext(选项))
{
context.Items.Add(结果);
SaveChanges();
}
//提交事务如果所有命令都成功,事务将自动回滚
//如果其中一个命令失败,则释放该命令
transaction.Complete();
}
捕获(系统异常)
{
//TODO:处理失败
}
}
}
您应该根据需要调整代码,但您有一个想法
尽管如此,我还是希望完全避免这个问题,不修改任何记录,而是插入它们,然后选择最新的记录。事务在应用程序中很棘手,它们可能会导致性能下降,并导致死锁以错误的方式应用在错误的位置。我不是在修改记录。我正在选择和插入。在插入完成之前,您的代码是否锁定任何选择?确切地说,IsolationLevel.Serializable阻止其他用户在事务完成之前更新或将行插入表中。在这里阅读关于可序列化隔离级别的更多信息:在这里:我已经检查了您的建议,但仍然得到了连续的副本。我用一个代码示例更新了我的问题。请你看看好吗?