【问题标题】:Where should IsChanged functionality be handled?IsChanged 功能应该在哪里处理?
【发布时间】:2010-12-06 00:34:23
【问题描述】:

我正在内部争论我应该在哪里处理检查数据更改,并且无法决定最有意义的做法:

  1. 在 GUI 中处理 IsChanged - 这需要在页面加载和数据发布之间保持数据的持久性,这可能会增加大量带宽/页面交付开销。这在 win forms 应用程序中还不错,但在网站中,这可能会对带宽成本产生重大的财务影响。
  2. 在 DAL 中处理 - 这需要多次调用数据库以检查是否有任何数据在保存之前发生了更改。这可能意味着对数据库的额外不必要调用可能会导致不必要的数据库查询导致可伸缩性问题。
  3. 在 Save() 存储过程中处理它 - 这将需要存储过程潜在地对表进行额外的不必要调用以进行检查,但会将 DAL 的额外调用保存到数据库。这可能比让 DAL 处理更好,但我的直觉认为这可以做得更好。
  4. 在触发器中处理它 - 这需要使用触发器(我在情绪上很反感,我倾向于避免触发器,除非绝对必要)。
  5. 根本不处理 IsChanged 功能 - 不仅难以处理“LastUpdated”日期,而且将不必要的数据保存到数据库似乎本身就是一种不好的可伸缩性做法。

因此,每种方法都有其缺点,我不知道哪种方法最好。有没有人有任何更具可扩展性的想法来处理数据持久性,以查看是否有任何变化?

架构:SQL Server 2005、ASP.NET MVC、IIS7、非特定全球受众的可扩展性要求。

【问题讨论】:

  • 愿意分享您的软件上下文吗?使用场景,使用的数据库,用户群等......我认为你的观点是有效的,它们对于不同的上下文/场景各有利弊。

标签: asp.net architecture web-applications scalability


【解决方案1】:

好的,这是另一个解决方案 - 我还没有考虑过所有的影响,但我认为它可以工作:

想想 GetHashCode() 比较功能:

在页面加载时,您计算页面数据的哈希码。如果您愿意,可以将哈希码存储在页面数据或视图状态/会话中。

在数据发布(回发)时,您计算所发布数据的哈希码并将其与原始哈希进行比较。如果不同,则用户更改了某些内容,您可以将其保存回数据库。

  • 优点
    • 您不必在页面加载中存储所有原始数据,从而减少带宽/页面交付开销。
    • 您不必让 DAL 多次调用数据库来确定是否发生了变化。
    • 只有在发生更改时才会在数据库中更新记录,从而保持正确的 LastUpdated 日期。
  • 缺点
    • 您仍然需要将任何原始数据从数据库加载到您的业务对象中,这些数据未存储在将有效记录保存到数据库所需的“视图状态”中。
    • 改变一个字段会改变hash,但你不知道是哪个字段,除非你从数据库中调用原始数据进行比较。顺便说一句,也许你不需要。如果您必须更新任何字段,则时间戳会发生变化,并且覆盖未出于所有密集目的而更改的字段不会产生任何影响。
    • 您不能完全排除发生碰撞的可能性,但它们很少见。这归结为碰撞的影响是否可以接受?
  • 非此即彼
    • 如果您将哈希存储在会话中,则可以节省带宽,但会增加服务器资源,因此在任何一种情况下都需要考虑潜在的可扩展性问题。
  • 未知数
    • 更新单个列的开销是否与更新记录中的多个/所有列的开销不同?我不知道性能开销是多少。

【讨论】:

  • 鉴于哈希码是 1/10^42 并且这个应用程序中的数据不是生死攸关的问题,我会说这是一个合理的解决方案。
  • 我接受了这个答案,因为它实际上似乎是最优化的解决方案。它将交付开销/带宽降至最低,而无需在会话中保存不必要的数据,并防止数据库中不必要的更新。总的来说,这最好地解决了其他解决方案中的可扩展性缺陷。
  • @BobTheBuilder - 感谢您的反馈。我还想听听其他人对这种方法的看法,因为我正在考虑在我的下一个项目中使用它,并希望了解潜在的缺点。
【解决方案2】:

我在 DAL 中处理它 - 它包含原始值,因此无需访问数据库。

【讨论】:

  • 根据 DAL 的设计/实现,可能不会保留这些值,是吗?
  • 我想过,但 DAL 在 Post 时没有原始值,而无需从数据库中加载它们。要保存的业务对象将从 Post 数据中加载。
  • 这就是为什么我让我的 DAL 保持原始值 - 这是我的设计,其他人可能决定不这样做是正确的,但对我来说,它一次又一次地得到了回报。
  • @ocdecio - 您能否详细说明原始数据的存储位置?即您的 DAL 是在维护缓存还是将一些原始数据缓存加载到您的业务对象中?
  • 所以你基本上是说选项列表中的第二个是最好的?
【解决方案3】:

为系统中的每个实体引入额外的 Version 字段。使用此字段,您将能够检查数据库级别的更改。

由于您有一个 Web 应用程序,而且 Web 应用程序的可伸缩性通常很重要,我建议您在 UI 级别避免 IsChanged 逻辑。 LastUpdated 日期可以在保存操作期间在数据库级别设置。

【讨论】:

  • 我倾向于使用 Version 字段进行并发:因为它并没有真正处理“你已经更改了这条记录”,而是处理“自从你加载它以来,这条记录在数据库中已经发生了变化。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-26
  • 2022-01-17
相关资源
最近更新 更多