处理C#服务中的死锁

时间:2012-08-21 11:59:26

标签: c# service

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

自从作为服务后,它会在每5秒后被调用一次。

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

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

4 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

听起来你需要等待插入Oracle才能完成,因此在c#中排队请求,即同步执行。考虑使用Mutex对象。

答案 2 :(得分:0)

我认为你有几个选择。

  1. 不要经常运行服务,特别是如果没有必要的话。你说你的服务每5秒钟就会收到20,000条记录 - 对于那些大小的东西来说,这似乎很常见。
  2. 在更新完成之前对Oracle表发出锁定,以便所有读取操作都必须等待。
  3. 不要在计时器上启动服务委托,而是在事件上启动服务委托。因此,当您第一次启动该服务时,您将手动触发该事件,但此后每次引发的事件都将在更新完成后发生。
  4. 我个人更喜欢选项#3。

答案 3 :(得分:0)

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

  1. 使用 AutoResetEvent 实例创建静态字段。
  2. 计时器调用的方法应该在启动时通过 AutoResetEvent.WaitOne(TimeSpan timeout)调用来检查此实例。
  3. 在您的方法结束时(由计时器调用)始终调用 AutoResetEvent.Set() try {} finally {} 构建通常可以用于此次调用。
  4. 在服务启动期间,为创建的实例调用 AutoResetEvent.Set()以允许方法(由计时器调用)启动 工作
  5. 使用具有小超时的 WaitOne(TimeSpan超时),如果前一个尚未完成,则可以快速完成定时器“呼叫”。所以你仍然能够每5秒调用一次方法。

    在调用其方法之前,确实需要检查AutoResetEvent的处理方式,也许还需要进行一些额外的检查......