2012-03-22 64 views
2

我正在研究收集有关某个帐户的(last_x,counters)信息的项目。 用户操作可能会导致生成多个业务事件。当Web上的单个用户操作导致多个事件时,它将触发USER HISTORY表的更新。是否有乐观锁定的替代方案

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

问题:

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

解决方案的尝试:

  • 每一个事件的结果插入到用户履历表 - 更多的历史信息,导致读取性能较差。

有没有其他的选择?

+0

你能写出记录而不是更新吗?因此没有潜在的冲突。 – davidfrancis 2012-03-22 23:43:46

+0

写入将导致网站中的用户事件与用户历史记录表中的记录之间的一对一映射。由于它是一个有计数器变量和last_X变量的表。我们需要最新的纪录。这意味着我们必须在加载之前对所有事件进行排序。这会导致读取性能差。 – 2012-03-22 23:46:30

+0

立即更新它有多重要? – Ben 2012-03-22 23:52:13

回答

2

是否有重写需要在此表上有读取性能?

这听起来像是某种'营业日结束'/每小时左右,客户简介/情报表。如果是这种情况,那么你可以使用插入和思考数据服务技术,如Star Schema来照顾(last_x,counter)方面的事情。

如果它更关键和时间依赖,那么你的模式可能不适合这项工作。您是否考虑过使用消息中间件(例如JMS)来通知并触发其他业务事件?

由于您使用的是Oracle,你可以看看:Oracle AS

[编辑]根据讨论,你的计数器信息的实时生产者/消费者。我不认为数据库是解决这个问题的基本方法。您可能需要守住计数器计算的目的,所以也许这样的事情是你所需要的:

监制:初始化(重建从DB会话/ memcached的)
RECV用户操作X - >会议/ Memcached的(ActionX)+插入到数据库。

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

你甚至可以让用户历史柜台的消费者是订户由生产者当计数器达到X和触发的事件消除消费者对用户历史的依赖

+0

数据仓库不是一种选择,因为我们需要实时数据。我们使用触发写入的JMS。如果有多个事件,那么它们会触发同时写入相同的记录。我们通过乐观锁定来解决冲突,但这会导致过度的读取和写入。我们想避免这种情况。 – 2012-03-23 00:13:24

+0

是否需要实时阅读历史记录表?如果柜台达到一定水平,还有什么需要启动的?基本上,写作历史表并在历史表上扮演两件不同的事情?历史需要在那里进行核算,但是如果计数器击中X,需要立即发生一些事情? – 2012-03-23 00:15:21

+0

是的,我们确实采取了基于计数器和变量生命周期的操作。 – 2012-03-23 00:16:25

0

听起来像这些多个事件遵循不同的路径,并且每个事件导致历史记录。那是对的吗?

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

+0

是的。不同的事件遵循不同的路径所以他们不知道另一个。是的,我们有一个重试逻辑,但会导致更多的读取和写入。我们正在努力避免这种情况。 – 2012-03-23 00:10:59

+0

在这种情况下,为什么不能为每个事件生成一个UNIQUE标识符并将该标识符传递给该事件的每个克隆?在这种情况下,DB将通过忽略具有相同唯一ID的多个写操作来简单地处理唯一约束(假设您可以使您的模式对事件的ID执行唯一约束)。 – uaarkoti 2012-03-23 00:14:35

+0

如果事件ID是唯一键的一部分,那么它将避免违反唯一约束。但是,如果事件A在事件B写入之前从数据库读取,该怎么办?在这种情况下,事件A正在更新过时的信息,当它写入时,我们失去事件B的信息,因为唯一约束不会因事件ID而失败。 – 2012-03-23 00:20:00