我有一个使用HTML5画布的HTML5前端。画布显示一组用户可以操作的图像(移动它们),然后单击“保存”。然后,“保存”将图像数据列表(如x,y坐标)发送到asmx Web服务。
目前:我正在删除会话的所有记录并重新插入新记录,但是如果会话从未保存过,那么我正在插入。
我的第一个问题是建议删除和插入或只是运行更新。哪一个在计算上不那么密集?
其次,我想确保所有会话数据都已提交,即如果我发送了46行数据,我想确保它们被写入。在删除/插入方案中,删除可能会继续,而插入可能会失败。
如何使用交易完成此任务。
目前我只使用实体框架,选择会话数据,删除它,然后重新重新插入数据。
任何指针都会非常感激。
答案 0 :(得分:1)
我的第一个问题是建议删除和插入或只是运行更新。哪一个在计算上不那么密集?
更新比删除和插入便宜。原因是瓶颈是磁盘(不是计算)。插入和删除在磁盘上的页面中分配和释放字节,可能需要更新一两个索引。更新将使它们保持原位并仅更改几个字节,因此IO更少。最重要的是,插入和删除是两个操作(+这将影响的任何索引),而只有一个用于更新。 (通过btw记录会有更多的开销)
如果您使用的是sql2008或更高版本,则可以使用table valued parameters,这些应该可以很好地用于您所描述的内容,因为您可以在一次往返中将整个更新集发送到sql。如果使用常规更新语句,则需要运行46个语句。
如果您真的想要调整它,您可能还需要查看combining the TVP's with the merge statement以在单个操作中处理混合更新和插入。
话虽如此,您可能只想使用代码中最简单的方法。如果您没有性能问题,则无需修复。
其次,我想确保所有会话数据都被提交,即如果我发送了46行数据,我想确保它们被写入。在删除/插入方案中,删除可能会继续,而插入可能会失败。
您确实可以使用事务来进行更新或删除/插入。
begin tran
delete * from table where some condition
insert into table (value1, value 2) values (1, 2), (3, 4) ..
commit tran
这将作为一个整体成功或不更改数据库。这也适用于使用表值参数。
答案 1 :(得分:0)
与TVP一起查看MERGE声明
我还创建了一个临时表,并使用了SqlBulkCopy类(当然是MERGE),效果很好。 SqlBulkCopy通常用于更多行,但它使用起来很简单(比TVP更多),因此在这些条件下使用它不会造成任何伤害。
另一个替代方法是执行临时表和大量插入,然后进行合并。通过一次往返发送所有指令,您将获得良好的性能。如果你想我猜你也可以做46个合并语句 - 你必须对你的值进行内联选择。
在所有情况下,事务都是合适的,但前两个事项并非严格必要,因为MERGE是原子的。如果你开始做更多的事情,还是一个很好的习惯。