jim*_*jim 3 c# sql-server asp.net optimistic-concurrency
我正在使用c#和asp.net为我的网站创建一个论坛系统,对于数据访问,我使用的是类型化数据集,对于UI,我正在使用mvp模式.在我的数据库中,我有存储过程,我已添加到我的数据集中.问题是数据集不允许我选择"使用乐观并发"复选框,所以我必须自己实现乐观并发.我已经为我的表添加了一个时间戳列,现在我遇到了为每个用户保存此值的问题!那么什么状态管理方法是安全的,并且用于保存时间戳值的成本更低?
我想也许最好使用session来存储值,但是如果用户的数量增加,我会遇到内存资源问题但是我可以设置会话使用sql server而不是内存但我不知道会慢多少所以我无法决定.
任何帮助是赞赏的家伙!
编辑1:是的.我想跟踪行的最后一次修改,看它是否与用户拥有的那个匹配.但我不知道在哪里保存用户的时间戳值.
如果由于某种原因你不能使用timestamp/rowversion它是一个论坛类型的应用程序我会猜你跟踪发布创建/修改日期/时间?如果是这样,这将是一件容易检查的事情.
更新
SQL Server模式
SQL Server Mode的用例通常是Web服务器场,因此ASP.NET会话状态在多个服务器上保持不变.这使得它更加健壮,因为如果Web服务器变得不可用,只要另一个可用,会话就可以正常继续.SQL Server模式没有本地快,除非资源受到严重的争议,因为我们正在查询数据库而不是同一服务器的内存(进程外)或甚至是同一进程(进程内).
MVC模式和会话状态
如果您在应用程序中使用WebFormViewEngine,则可以使用state,但MVC模式的主要租户是无状态的.
如何跟踪rowversion/timestamp无状态
为了以无状态的方式跟踪rowversion,我们需要将它返回给客户端,这样当回调到控制器动作时,它就会被提供给我们.
<%= Html.HiddenFor(Model.VersionId) %>
Run Code Online (Sandbox Code Playgroud)
这将导致生成的HTML表单中的隐藏字段.
<input type="hidden" name="VersionId">1</input>
Run Code Online (Sandbox Code Playgroud)
安全吗?
将此临时存储在客户端上是否安全,完全知道可能有人可能会在攻击您的Web应用程序时改变该值.
让我们分析一下我们所知道的:
基于此,我们将编写我们的应用程序以使用rowversion,以便我们使用rowversion来确定记录是否在我们当前请求的更新之间发生了变化.我们将始终让DB在内部增加rowversion.因此,存储过程将接受该值以进行比较,但不在表/视图中插入或更新它.
那么如果有人试图操纵它,那么rowversion可能会出现什么情况.
让我们打破这一点.
那么如果客户端rowversion小于DB那意味着什么呢?
客户端在编辑数据时使用了旧数据副本,因为自上次从数据库读取数据后,客户端已经发生了更改.为了解决这个问题,我们可以:
A.给他们一个错误,重新加载数据并让他们重新提交他们的更改.
B.将他们的更改合并到当前副本中,并在重新提交之前要求确认.
C.覆盖DB中的现有副本.好吧,我们可以做到这一点,但由于我们实现了一个并发模型来同时处理多个更改,它可能不是最合适的.这给我们留下了A和B.
另一个选项是客户端将rowversion的值更改为小于实际的DB值.在这种情况下,即使他们确实改变了rowversion的价值,这也很重要吗?我建议它不会,并且应该像处理与另一个用户同时更改一样处理.再次返回选项A和B.
因此,如果客户端rowversion等于DB,那意味着什么?
客户端正在编辑他们期望的版本并点击提交按钮.为了解决这个问题,我们可以:
A.接受他们的更改并继续.
B.拒绝更改并提供反馈消息.我们不太可能想要这样做,因为它总是将数据输入数据库.
另一个选择是客户端将rowversion的值更改为我们期望的正确版本,或者很可能根本没有修改它,因为我们告诉他们我们所期望的rowversion与我们为所有提交做的一样.但是,如果他们确实改变了rowversion,并且同时发布了他们的更新客户端,这是要提交的最后一次更新.
我们可以像A或B之前那样处理这种情况.不幸的是,我们无法知道它们实际上修改了rowversion,因为它符合预期.但是我们已经允许他们对记录进行更新.如果他们不应该更新记录,那么他们就没有权限这样做.
也就是说,在将其写入数据库之前,我们仍将验证所有输入的完整性并对其进行消毒.
如果这不好,那么我们需要在我们的应用程序中实现内容版本控制或批准过程,以便在我们更新每条记录或允许回滚到先前版本之前让我们控制.
因此,如果客户端rowversion大于DB,这意味着什么?
那么选项与rowversion小于DB的情况完全相同.这不是预期的,所以A或B.再次C可能不是一个选项,因为它击败了目的.
结论
那么论坛Web应用程序是否安全?我们仍然需要验证输入,但如果rowversion与预期不同,我们有解决方法.
作为最后的手段,我们还可以对rowversion进行编码或加密,以防止序列被轻易猜到.
所以在我看来是的,但这最终是你的号召.
| 归档时间: |
|
| 查看次数: |
1848 次 |
| 最近记录: |