1

我在路由器后面有一个 DB Worker 演员池,通过 Dao 阻止 DB 操作。如果您尝试将相同的 foo 插入两次,则将(“放置”) foo 对象插入 Dao 会引发 DuplicateKeyException。在这种情况下,我想回复 DuplicateFoo(foo) 消息;成功后,我想用 FooAdded(foo) 来回应。这就是我的做法;有没有更好的办法?

def receive = {
  case PutFoo(foo) =>
    try {
      dao.put(foo)
      sender ! FooAdded(foo)
    } catch {
      case DuplicateKeyException(_) =>
        sender ! DuplicateFoo(foo)
    }
}

抛出 DuplicateKeyException 后,Dao 可以继续处理请求,所以我觉得没有必要重新启动 worker。

4

1 回答 1

1

从理论上讲,您所做的是“包含”检查,然后“放置”或“通知”。从实际的角度来看,它的实现方式是“放置”,如果地狱失控,则“通知”。

由于理论上不存在意外行为,因此put 在失败情况下的实现并不理想。如果需要唯一性,则应进行“包含”检查,因此put(或PutFoo在您的场景中)应返回 Status(Success|Failure),即使它尝试“放置”并在DuplicateKeyException内部捕获。采取Boolean, or Optionor or or Eitheror Tryor your own status ADT 为此,但不要为您希望不时发生的事情抛出异常。

如果没有例外,则无需重新启动工人,但我猜您的直觉一直试图告诉您这一点。;)

于 2013-04-13T04:55:38.937 回答