2

我有一个使用 HTML5 画布的 HTML5 前端。画布显示一组用户可以操作(移动)的图像,然后单击“保存”。“保存”然后将图像数据列表(例如 x,y 坐标)发送到 asmx Web 服务。

目前:我正在删除会话的所有记录并重新插入新记录,但是如果之前从未保存过会话,那么我正在插入。

我的第一个问题是建议删除和插入还是简单地运行更新。哪一个计算量较小?

其次,我想确保所有会话数据都已提交,即如果我发送 46 行数据,我想确保它们已被写入。在删除/插入场景中,删除可能会继续,而插入可能会失败。

如何使用事务来实现这一点。

目前我只是使用实体框架,选择会话数据,删除它,然后重新插入数据。

任何指针将不胜感激。

4

2 回答 2

1

我的第一个问题是建议删除和插入还是简单地运行更新。哪一个计算量较小?

更新比删除和插入便宜。原因是瓶颈是磁盘(不是计算)。插入和删除在磁盘上的一个页面中分配和释放字节,并且可能需要更新一个或两个索引。更新会将它们留在原处,并且只会更改几个字节,因此 IO 会更少。最重要的是,插入和删除是两个操作(+这会影响的任何索引),而只有一个用于更新。(顺便说一句,日志记录会产生更多开销)

如果您使用的是 sql2008 或更高版本,则可以使用表值参数,这些对于您所描述的内容应该非常有效,因为您可以在一次往返中将整个更新集发送到 sql。如果您使用常规更新语句,则需要运行 46 条语句。

如果您真的想调整它,您可能还想考虑将 TVP 与合并语句结合起来,以在单个操作中处理更新和插入的混合。

话虽如此,您可能只想使用代码中最简单的方法。如果您没有性能问题,则不必修复它。

其次,我要确保所有会话数据都已提交,即如果我发送 46 行数据,我要确保它们已写入。在删除/插入场景中,删除可能会继续,而插入可能会失败。

您确实可以使用事务,用于更新或删除/插入。

begin tran 

delete * from table where some condition

insert into table (value1, value 2) values (1, 2), (3, 4) .. 

commit tran

这将作为一个整体成功或不更改数据库。这也适用于使用 table value 参数。

于 2013-08-30T21:48:08.323 回答
0

结合 TVP查看MERGE语句

我还创建了一个临时表,并使用了SqlBulkCopy类(当然后面是 MERGE),效果很好。SqlBulkCopy 通常用于更多行,但使用起来很简单(比 TVP 更是如此),因此在这些情况下使用它不会造成任何伤害。

另一种选择是做一个临时表和大量插入,然后合并。通过在一次往返中发送所有指令,您将获得良好的性能。如果您愿意,我猜您也可以执行 46 个合并语句 - 您必须对您的值进行内联选择。

在所有情况下,事务都是适当的,尽管对于前两个不是绝对必要的,因为 MERGE 是原子的。如果你开始做更多的事情,这仍然是一个好习惯。

于 2013-08-30T23:39:15.617 回答