使用 PostgreSql 和 ADO.NET 在 C# WinForms 中锁定记录和表

Posted

技术标签:

【中文标题】使用 PostgreSql 和 ADO.NET 在 C# WinForms 中锁定记录和表【英文标题】:Record and Table locking in C# WinForms with PostgreSql and ADO.NET 【发布时间】:2016-12-26 15:12:49 【问题描述】:

我正在使用 .NET Framework 4.6.1、WinForms、PostgreSQL 6.4beta4 和 Npgsql 和 ADO.NET。

我当前的应用程序是一个多用户应用程序,所有用户都连接到同一个数据库。

使用 DataTable、BindingSource 和 BindingNavigator 将数据绑定到控件。

我想避免两个用户可以同时编辑一个 DataRow。 因为我想以更通用的方法实现这一点,所以我正在考虑创建一个 DataTable 后代并添加属性 LockMode (None, Row, Table)

我发现您可以结合使用 ColumnChanged 事件和 RowState 来检测数据的变化。

我现在知道用户是在插入新值、编辑(RowState = 已修改)现有值还是只是查看(RowState = 未更改)记录。

因此,我正在寻找一种解决方案,以便在用户开始编辑 DataRow 时对其进行锁定。在应用程序中,一旦用户导航(通过使用 Bindingnavigator 或以编程方式)到锁定的记录,我想显示一条消息。

我发现的大多数解决方案都以这样的 mysql Server 为目标:How to perform a row lock? 或 TransactionScope locking table and IsolationLevel。

但是我正在寻找一个 PostgreSQL 解决方案,所以即使是来自 MS (https://msdn.microsoft.com/en-us/library/system.transactions.transactionscope(v=vs.110).aspx) 的关于这个主题的文章也不能在这里使用。

如果有 PostgreSQL 和 ADO.NET 经验的人可以在这里帮助我,我将不胜感激。谢谢。

【问题讨论】:

在 NET 中,您从客户端加载的数据与数据库中的数据“断开连接”,因此没有链接。对该数据的编辑通常无关紧要,因为它们很容易被撤消/丢弃。此外,如果有人开始编辑一行并被重要电话打断怎么办?您是否希望所有用户在此期间都被锁定?如果他们然后去吃午饭或被老板叫走怎么办? 是的,如果有人开始编辑一行,我想让其他用户无法对其进行编辑,即使这是在很长一段时间内。 最简单的解决方案可能是添加一个列(位),将行标记为处于编辑模式。一旦用户开始编辑,设置位 (1)。用户完成编辑后,设置位(0) 所以类似于这里接受的答案:***.com/questions/21284271/… ? 【参考方案1】:

您必须同步您的客户端才能实现这一点。

我会添加一个额外的可为空的日期列 (RowIsBeeingEdited),指示该行开始编辑的时间。我会将行设置为可编辑/不在客户端应用程序开始的行 [RowIsBeeingEdited] 值。

我还将实现两个信号:UserStartedEditingRowUserFinishedEditingRow,这将传播到所有客户端,表明客户端 X 开始/完成编辑行 Y .

在开始编辑行时,我将设置 row[RowIsBeeingEdited] = now 并发送 UserStartedEditingRow 信号。在结束编辑时,我会设置 row[RowIsBeeingEdited] = null 并发送 UserFinishedEditingRow 信号。当前活跃的客户端应该接收到这两个信号并设置行可编辑/不可编辑。

希望有一些价值。

【讨论】:

【参考方案2】:

@lok​​usking 提供的建议听起来不错。易于维护和扩展能力。

【讨论】:

【参考方案3】:

您应该在表中添加一个 RowVersion 或 Timestamp 类型的列,并将其用作更新语句中的并发标记,并在提交用户更改之前在值更改时引发并发异常。

【讨论】:

这没有提供问题的答案。一旦你有足够的reputation,你就可以comment on any post;相反,provide answers that don't require clarification from the asker。 - From Review

以上是关于使用 PostgreSql 和 ADO.NET 在 C# WinForms 中锁定记录和表的主要内容,如果未能解决你的问题,请参考以下文章

生成 .ADO.net 实体数据模型时,postgresql 不会出现在数据源中

在 Visual Studio 2015 中使用 ADO.NET 和 MySQL

ado.net 和 dapper 之间的交集/联合是啥?

如何使用 ADO.net 在视图中包含相关对象

ADO.NET 执行部分更新/插入

ADO.NET Entity Framework 和 NHibernate - 何时使用其中之一