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

12

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

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

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

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

我发现可以使用ColumnChanged事件与RowState结合使用来检测数据的更改。

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

因此,我正在寻找一种解决方案,以便在用户开始编辑DataRow时锁定它。在应用程序中,我希望当用户导航(使用Bindingnavigator或编程方式)到已锁定的记录时显示消息。

我发现大多数解决方案针对MySql服务器,例如: 如何执行行锁定?TransactionScope锁定表和隔离级别

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

如果有经验的PostgreSQL和ADO.NET用户能帮我解决这个问题,我将不胜感激。谢谢。


2
在.NET中,从客户端加载的数据与数据库中的数据是“断开连接”的,因此它们之间没有关联。对该数据的编辑通常不重要,因为它们很容易被撤消/丢弃。此外,如果有人开始编辑一行,然后被一个重要电话打断,你想要所有用户在此期间被锁定吗?如果他们接着去吃午饭或被老板叫走了呢? - Ňɏssa Pøngjǣrdenlarp
是的,如果有人开始编辑一行,我希望即使在很长一段时间内,其他用户也无法对其进行编辑。 - Thomas
2
最简单的解决方法可能是添加一个标记行处于编辑模式的列(bit)。一旦用户开始编辑,设置该位(1)。用户完成编辑后,设置该位(0)。 - lokusking
1
可以像这里所接受的答案一样实现:https://dev59.com/qHvaa4cB1Zd3GeqPFZtE? - Thomas
3个回答

0

你需要同步你的客户端来实现这个。

我会添加一个额外的可空日期列(RowIsBeeingEdited),表示行开始编辑的时间。我会根据 row[RowIsBeeingEdited] 的值在客户端应用程序启动时设置行是否可编辑。

此外,我会实现两个信号:{UserStartedEditingRow} 和 {UserFinishedEditingRow},它们将传播到所有客户端,指示客户端 X 开始/完成编辑行 Y。

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

希望这对你有一些价值。


0

@lokusking 提供的建议听起来不错。易于维护和扩展。


-1
你应该在表中添加一个 RowVersion 或 Timestamp 类型的列,并将其用作更新语句中的并发标记,在提交用户更改之前,如果值在更改时已更改,则抛出并发异常。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接