【问题标题】:Is there a Alternative to optimistic locking是否有乐观锁定的替代方案
【发布时间】:2012-03-22 23:36:43
【问题描述】:

我正在开展一个项目,我们收集有关帐户的(last_x,counters)信息。 用户操作可能会导致生成多个业务事件。当网络上的单个用户操作导致多个事件时,它将触发对 USER HISTORY 表的更新。

我们进行乐观锁定以确保所有事件都会导致对 USER HISTORY 表的更新。

问题:

乐观锁定会导致额外的读取(当检测到冲突时,再次读取并更新)和额外的写入(在解决冲突之后)。

已尝试的解决方案:

  • 每个事件都会导致插入到 USER HISTORY 表 - 更多历史信息,导致读取性能不佳。

还有其他选择吗?

【问题讨论】:

  • 你可以只写记录而不是更新吗?因此没有发生冲突的可能性。
  • 写入将导致网站中的用户事件与用户历史记录表中的记录之间的一对一映射。因为它是一个具有计数器变量和 last_X 变量的表。我们需要最新的记录。这意味着我们必须在加载之前对所有事件进行排序。这将导致读取性能不佳。
  • 立即更新有多重要?
  • 我猜几秒钟的延迟是可以的。但是当有多个事件时,哪个事件会等待呢?

标签: java oracle jakarta-ee nosql


【解决方案1】:

是否有压倒一切的需要才能在此表上读取性能?

在我看来,这是某种“工作日结束”/每小时左右的客户资料/情报表。如果是这种情况,那么您可以只使用插入并考虑数据仓库技术,例如 Star Schema 来处理 (last_x, counters) 方面的事情。

如果它更关键且与时间相关,那么您的架构可能无法胜任这项工作。您是否考虑过使用消息传递中间件(例如 JMS)来通知和触发其他业务事件?

由于您使用 Oracle,您可以查看:Oracle AS

[编辑] 根据讨论,您有一个计数器信息的实时生产者/消费者。我不认为数据库是解决这个问题的基本方法。出于会计目的,您可能需要保留柜台,所以您可能需要这样的东西:

生产者:初始化(从数据库重建会话/memcached)
RECV 用户操作 X -> 会话/Memcached(ActionX) + 插入数据库。

消费者:运行(检查会话/memcached 的条件,行动)

您甚至可以让用户历史计数器的消费者成为一个事件的订阅者,当计数器达到 X 时,生产者触发该事件,并消除消费者对 USER HISTORY 的依赖

【讨论】:

  • 数据仓库不是一个选项,因为我们需要实时数据。我们使用触发写入的 JMS。如果有多个事件,则它们触发同时写入同一记录。我们用乐观锁解决了冲突,但这会导致过多的读写。我们希望避免这种情况。
  • 需要实时读取历史表吗?如果计数器达到一定水平,是否还有其他需要启动的东西?基本上,写入历史表和作用于历史表是两件不同的事情吗?历史需要在那里进行核算,但如果计数器击中 X,则需要立即发生某些事情?
  • 是的,我们确实会根据计数器和变量的生命周期采取行动。
  • 那么,为什么计数器不能保留在会话中,通过插入历史表写入,但是当会话计数器达到目标值时(可能使用 JMS)起作用?如果一切都失败了,你可以恢复
  • 那么用户的USER HISTORY表就不是实时的了。
【解决方案2】:

听起来这多个事件遵循不同的路径,每个事件都会产生历史记录。对吗?

应用程序不应该能够控制事件并以某种方式指示其遵循不同路径的相同事件吗?就像可能为每个事件生成一个唯一的 ID 并使该字段在数据库中唯一,这样写入就会失败?由于唯一约束,您可以轻松忽略失败。

【讨论】:

  • 是的。不同的事件遵循不同的路径。所以他们不知道对方。是的,我们有一个重试逻辑,但这会导致更多的读取和写入。我们正在努力避免这种情况。
  • 在这种情况下,为什么不能为每个事件生成唯一标识符并将该标识符传递给该事件的每个克隆?在这种情况下,数据库将通过忽略具有相同唯一 ID 的多次写入来简单地处理唯一约束(假设您可以使架构对事件的 ID 强制执行唯一约束)。
  • 如果事件ID是唯一键的一部分,那么它将避免违反唯一约束。但是,如果事件 A 在事件 B 写入之前从 DB 读取会怎样。在这种情况下,事件 A 正在更新过时的信息,当它写入时,我们会丢失事件 B 的信息,因为唯一约束不会因为事件 ID 而失败。
  • 我的印象是您只想记录每个事件一次,即使它采用不同的路径。看起来您有兴趣将事件的所有路径记录为不同的条目。那么为什么当你有多个写入时它会出现问题呢?在这种情况下,每条路径都是不同的记录。也许我没有关注你的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-12
  • 1970-01-01
  • 1970-01-01
  • 2018-11-09
  • 2014-01-29
  • 1970-01-01
相关资源
最近更新 更多