【问题标题】:What is a good method to determine when an entities data has been changed on the database?确定何时在数据库上更改实体数据的好方法是什么?
【发布时间】:2011-09-02 05:46:57
【问题描述】:

假设,我使用实体框架从数据库中检索了一个实体。有没有办法随后检查另一个用户在数据库中更改了相同的特定实体?

我以前(在 WinForm 应用程序中)使用的方法是:

  • 将实体保存到数据库
  • 向 Transactions 表添加条目,更改实体类型、唯一标识符和日期时间
  • 刷新同一个实体时,检查事务表中当前用户保存后的行。
  • 如果找到条目,请采取相应措施(从数据库重新加载实体、阻止编辑、保存冲突等,具体取决于我检查更改的原因)。

我想这样做的原因是:

  • 避免重新加载整组实体,只需刷新已更改的实体
  • 在保存时检查并发冲突
  • 根据编辑开始的时间解决并发冲突。为此,我需要在用户开始编辑时在 Transactions 表中创建一个条目,并在用户保存/取消时更新同一 Transaction 表行。

这个方法看起来对吗?这样做的原因是否完全正确?也许已经有我无法找到的功能来做到这一点?

【问题讨论】:

    标签: .net entity-framework concurrency


    【解决方案1】:

    我想知道您为什么不使用一种更标准的乐观并发方式。 EF 为此提供了support。我认为单独的 Transactions 表只会增加复杂性,因为在对主要实体执行 CRUD 操作时,您总是必须显式维护该表中的条目。当用户开始编辑并在事务表中创建“锁定”条目但随后崩溃时会发生什么?在这里对数据库中的记录进行排他锁不合适吗(即悲观锁定)。

    您也可以使用这种方法来检查中间更改,因为您可以对时间戳或版本列执行轻量级查询。

    【讨论】:

    • 对不起,检查编辑措辞不当,已编辑问题。 EF ObjectContext.Refresh 和工作单元模式的问题是:如果我在整个应用程序中使用了一组“引用”对象,并且它们不会经常更改,为什么要从数据库中重新加载它们?此外,使用时间戳/版本列肯定比将信息存储在单独的表中效率低。但最终,你是对的,除非我有充分的理由应该使用标准 EF 并发而不是自己动手。
    • 你通常会通过一个短暂的 ObjectContext 从数据库中获取这些不可变的引用数据,之后它们独立地存在于你的应用程序中。至于你的第二点:效率低?更新是在一条记录上而不是在两条记录上。无论如何,是的,DBMS 可能比你我更擅长事务管理。
    • 嘿嘿,但问题是参考数据不是-完全-不可变的......而且更新工作的加倍超过了多个客户端仅读取一个事务表以确定更改的偏移量。鉴于通过管理您自己的并发性所获得的收益几乎不会超过使用广泛使用的 DBMS 的好处,我将您的答案标记为正确。感谢您的 cmets。
    猜你喜欢
    • 1970-01-01
    • 2012-02-28
    • 2011-05-27
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    • 1970-01-01
    • 2013-04-05
    • 2012-10-23
    相关资源
    最近更新 更多