3

我正在开发一个应用程序,其中我有一个数据集(它代表一个访问数据库),其中有几个数据表。然后我有线程同时在各种数据表中插入/编辑/删除行。

有时我有一个线程将数据表更改提交到数据库(在每个数据表上调用更新方法)。我的问题是数据表有一些被违反的关系。让我举个例子,我在将更改提交到数据库的线程中有这个:

If DS.Tables.Contains("TableA") Then SyncLock DS.Tables("TableA") : TableADataAdapter.Update(DS.Tables("TableA")) : End SyncLock
If DS.Tables.Contains("TableB") Then SyncLock DS.Tables("TableB") : TableBDataAdapter.Update(DS.Tables("TableB")) : End SyncLock

TableA 是 TableB 的父级,因此有一个 ID 列,TableB 中的每条记录都必须在 TableA 中具有相应的值

有时在 TableA 更新后,线程会在 TableA 和 TableB 中插入一条记录,当我更新 TableB 时,TableA 中缺少父记录并且关系中断(引发异常)

我试图锁定 DataSet 以查看 DataSet 中的所有 DataTables 是否都会成为锁定对象,但异常仍然存在。

SyncLock DS: Do The Updates : End SyncLock

我的问题是:有什么方法可以同时锁定所有数据表,以便我可以安全地更新数据库?

感谢您的任何建议

4

2 回答 2

3

因此,最终的解决方案是锁定每个 DataTable 的单个对象,然后在我想更新时将它们全部锁定:

在不同线程中修改行时:

SyncLock DataTableALock
    Insert/Edit/Delete Rows
End SyncLock

SyncLock DataTableBLock
    Insert/Edit/Delete Rows
End SyncLock

当我想提交更改时:

SyncLock DataTableALock
    SyncLock DataTableBLock
        Commit Changes
    End SyncLock
End SyncLock

我认为这段代码是安全的,并且每次我想更改一行时都不会锁定整个数据集(只是单个 DataTables)。它只是丑陋,但我可以忍受。

于 2013-09-17T10:11:19.097 回答
0

总而言之,我需要更新我的所有 DataTables,同时我知道关系得到尊重,为此我需要在此过程中停止/停止对 DataTables 的任何更改。

这个问题的一个可能的解决方案,但一个糟糕的解决方案,并且有很多可能出错,是放置一个表示更新的公共标志,然后在我进行数据表更改的每个地方检查该标志值。像这样的东西:

If UpdateIsRunnig = True Then 
   Do While UpdateIsRunnig = True : Loop
End If
Insert/Edit/Delete Rows in Datatable

这是非常危险的,它不能保证在我将更改提交到后端数据库时不会发生更改。所以这是一个糟糕的和部分的解决方案。我会尝试弄清楚是否有更好的方法来做到这一点。任何帮助深表感谢。

编辑:正如 PHeiberg 所指出的,我唯一真正当前的解决方案是拥有一个全局 SyncLock 对象,我在对 DataSet 所做的每次更改中都使用该对象,然后在更新中使用它。像这样:

SyncLock GlobalDataSetLock
    Insert/Edit/Delete Rows
End SyncLock

并在更新:

SyncLock GlobalDataSetLock
    Commit Changes to DataBase using "Update"
End SyncLock

这是一个解决方案,它确实解决了问题,但性能问题是巨大的。正如我在评论中所说,我真的不需要锁定 DataTable A 来更改 DataTable B,所以锁定整个 DataSet 只是为了稍后进行更新真的很令人沮丧。

于 2013-09-17T07:59:48.080 回答