在我尝试解决问题时,我已经问过few questions today。
我们有一个复杂的数据结构,其中所有各种实体都紧密相连,几乎所有实体都严重依赖/依赖于其他类型的实体。
该项目是一个网站(MVC3,.NET 4),所有逻辑都是在业务层使用LINQ-to-SQL(2008)实现的。
我们需要做的是让用户在进行更改时“锁定”系统(还有其他原因,我不会在这里与数据库相关)。当该用户进行更改时,我们希望能够向他们显示他们正在更新的实体的原始状态,以及他们所做的更改的“预览”。完成后,他们需要能够回滚/提交。
我们考虑过这些选择:
我们有点难以找到一个相对容易维护的解决方案。有什么建议吗?
答案 0 :(得分:1)
我们对类似问题的解决方案是使用一个锁定表来保存系统中每个实体类型的锁。当客户端应用程序想要编辑实体时,我们执行“GetWithLock”,它为客户端提供实体数据的最新版本以及获取锁定(存储在锁定表中的GUID以及实体类型和实体ID)。这可以防止其他用户编辑同一个实体。使用更新提交更改时,通过从锁定表中删除锁定记录来释放锁定。由于存储过程是我们用于与数据库交互的API,因此可以非常直接地锁定/解锁对特定实体的访问。
在客户端,我们在UI模型类上实现IEditableObject。我们的模型类包含对在服务调用上检索的服务实体实例的引用。这允许UI执行开始/结束/取消编辑,并根据需要执行提交或回滚。通过保存原始服务实体的实例,我们可以看到原始数据和当前数据,这将允许用户获得您正在寻找的“预览”。
虽然我们的解决方案没有实现LINQ,但我不相信我们的方法中有任何独特的东西会妨碍您使用LINQ。
HTH
答案 1 :(得分:0)
考虑一下:
答案 2 :(得分:0)
使用一组辅助表格。
问题是您的连接应该看到两个版本的数据,而其他连接只能看到一个(或两个,其中一个是他们自己的)。
虽然理论上可以并且使用闪回在Oracle
中实现,但SQL Server
本身不支持它,因为它无法查询以前版本的记录。
您可以发出如下查询:
SELECT *
FROM mytable
AS OF TIMESTAMP
TO_TIMESTAMP('2010-01-17')
在Oracle
但不在SQL Server
。
这意味着您需要自己实现此功能(将新版本的行放入您自己的表中)。
答案 3 :(得分:0)
听起来像一个丑陋的问题,并提出了很多你无法在SO上提出的问题。我在阅读你的问题时得到了以下想法,虽然它“闻起来”和你列出的其他人一样糟糕,但它可以帮助你制定最终的解决方案。
首先,如@ user580122所述,使用某种锁定系统来标记/记录其中一个事务正在进行的事实。 (务必包括某种定期的自动检查,以测试丢失或遗弃的交易!)
接下来,对于您对数据库所做的每一项更改,都要以某种方式记录它,无论是在应用程序中还是在某个专用表中。这个想法是,给定X状态下数据库的副本,您可以随时重新运行用户提交的步骤。
接下来要弄清楚如何使用数据库快照。在BOL中阅读这些内容;一般的想法是你创建一个数据库的时间点快照,做任何你想做的事情,并最终扔掉它。 (仅适用于SQL 2005及更高版本,仅适用于企业版。)
所以:
是的,这肯定闻起来,它可能不适用于您的问题。希望这里的想法可以帮助你解决问题。