哪种方法可以更快地阻止重复事务?我有一个基于SOAP的网关,它接收以下请求:
<soap:Body>
<ProcessItem>
<Item>
<ItemType>int</ItemType>
<ItemName>string</ItemName>
</Item>
</ProcessItem>
</soap:Body>
现在我不能保存具有相同名称和类型值的项目。我有两个选择:
进行验证,从而以编程方式防止重复 - 例如:
if (!ItemReposioty.Exists(concreteItem))
{
ItemRepository.Save(concreteItem);
}
else
{
return DuplicateStatus();
}
在MS SQL Server表中使用唯一约束或索引,使字段类型和名称唯一,从而防止在数据库级别重复。
try
{
ItemRepository.Save(newItem);
}
catch (SqlException e)
{
return DuplicateStatus();
}
答案 0 :(得分:1)
将它放在数据库端是最好的方法。如果两个代码实例同时运行怎么办?您仍然可能会获得重复项。
并且,如果将来创建另一个更新数据库的进程,绕过您的代码,它可能不会检查重复项。
将唯一索引放在数据库上可确保不会发生重复。在尝试插入之前,您仍然可以检查重复项,但数据库应该有最终决定权。
答案 1 :(得分:1)
为了直接回答你的问题,我认为在大多数情况下,后一种方式可能更快,因为它不需要进行两次数据库调用。
我会选择以前的方式,虽然我当然也会设置正确的数据库方面的约束。我认为(尽管不确定)ORM或其他操作背后的代码可以有效地执行 - 也就是说,我希望存在检查比写操作快得多。此外,与HTTP请求的整体延迟相比,通过LAN访问数据库的速度很快,因此弄清楚如何将两个数据库操作合并为一个可能是天真的优化。
在后一种情况下,您需要确保导致的SqlException是由于重复的密钥冲突 - 其他SqlExceptions可能由于其他原因而发生,并且您可能不希望以相同的方式处理它们。
为了使前一个解决方案更加健壮,您可能希望在事务中执行这两个操作,以便可以保留来自第一个查询的任何锁定,并且使用存在性检查进行原子更新。