1

我在 C# 中有一项服务,它从 oracle DB 中获取记录并插入到 MySql DB 中,在成功插入 MySql DB 中的所有记录后,我的 Oracle DB 的一列得到更新,即插入了这么多记录。

由于是一项服务,它每 5 秒就会被调用一次。

我的问题是我应该如何处理这种情况下的死锁情况。就像我的服务从 oracle DB 获取大约 20,000 条记录并尝试插入到 MySql DB 大约需要 7-8 秒,这意味着我的服务将被调用,并且由于之前会话的所有记录都没有被插入,所以不会在 Oracle DB 中更新,下次它会再次获取我不想要的全部记录。

如果可能的话,也提供一些相同的代码。这是纯粹的 Window 基础服务,而不是 WCF。

4

4 回答 4

0

我不知道你的功能要求是什么,但听起来你真的不想在你的服务中开始处理,直到之前的任何运行完成之后。即,您需要某种系统来判断退出运行是否正在进行,然后在开始后续进程之前检查这一点。另一种选择是将请求排队,然后将它们作为一个批处理,有效地删除重复。

于 2012-08-21T12:06:47.307 回答
0

听起来您需要等待插入 Oracle 完成,因此在 c# 中对您的请求进行排队,即同步执行。研究使用 Mutex 对象。

于 2012-08-21T12:07:10.000 回答
0

我想你在这里有几个选择。

  1. 不要频繁地运行该服务,特别是如果它不是真的必要的话。你说你有一项服务每 5 秒收集 20,000 条记录——这对于任何规模的东西来说似乎都很频繁。
  2. 在更新完成之前对 Oracle 表发出锁定,以便所有读取操作都必须等待。
  3. 不要在计时器上启动服务委托,而是在事件上启动。因此,当您第一次启动服务时,您将手动触发事件,但此后每个引发的事件都会在更新完成后发生。

我个人更喜欢选项#3。

于 2012-08-21T12:08:55.353 回答
0

如果您仅在此服务中需要“协调”,请使用AutoResetEvent类。

  1. 使用AutoResetEvent实例创建静态字段。
  2. 计时器调用的方法应在启动时通过AutoResetEvent.WaitOne(TimeSpan timeout)调用检查此实例。
  3. 在您的方法结束时(由计时器调用)始终调用AutoResetEvent.Set()try{} finally{}构造通常可以用于此调用。
  4. 在您的服务启动期间,为创建的实例调用AutoResetEvent.Set()以允许方法(由计时器调用)开始工作。

使用带有小超时的WaitOne(TimeSpan timeout)允许在前一个尚未完成的情况下快速完成计时器“调用”。因此,您仍然可以每 5 秒调用一次方法。

在调用它的方法之前肯定需要检查 AutoResetEvent 的处理,也许还有一些额外的检查......

于 2012-08-21T12:50:37.627 回答