发帖    主题    评论    推荐    标签    作者    订阅    查搜    注册   登陆   关注
 
面向对象 设计模式 领域驱动设计 企业架构 框架 开发教程 微服务 CQRS 扩展性 并发编程 事件溯源 分布式 SOA
1 2 3 4 ... 8 下一页 Go 8

当eventSourceing遇到并发和事务将变得复杂

              
2011-11-04 17:14
赞助商链接

据个例子:有个 仓库 共享对象
仓库『
events
addEvent


A 线程 处理一个事务(里面会用到仓库对象)如果失败需要回滚 如果成功store event to disk
b 线程 处理一个事务(里面也会用到仓库对象)如果失败需要回滚 如果成功store event to disk

这时候如果操作event是顺序存入共享对象的events队列里,那问题将更加的复杂,例如:假设存入在event队列里面的顺序如下
A线程的 event1
B线程的 event3
A线程的 event4
B线程的 event5

这时候A 线程的事务是成功的他需要commint 并 store event 到磁盘
可B线程事务这个时候失败了,这时候事情将变的复杂话。
所以你就会发现这种设计最理想的是single-write规则,假如想多加入处理器的话,共享事件队列将会让问题变得很复杂。

10
2011-11-04 17:44

A做A的,B做B的,哪里复杂了?

1、事件本身就是相互独立的。
2、使用事务不是很适合逻辑的,因为逻辑是不讲究过程的,而回滚正是针对过程而存在。
3、多处理器不是问题,关键是处理的设计,可以看看下面的对比(event2在event1之后处理):

1)event1进入队列后,把event2放入队列;(计划任务)
2)event1进入队列后,待event1执行后才放入event2;(一件事完了才会有第二件事)

这里可以看出,不是队列很复杂,而是我们想得太简单了,发散一下思维,不要被原来理所当然的队列约束。

2011-11-04 22:04

2011年11月04日 17:44 "@SpeedVan"的内容
A做A的,B做B的,哪里复杂了?

1、事件本身就是相互独立的。
2、使用事务不是很适合逻辑的,因为逻辑是不讲究过程的,而回滚正是针对过程而存在。
3、多处理器不是问题,关键是处理的设计,可以看看下面的对比(event2在event1之后处 ...

还是不是很明白 ,event1处理完了,event2才开始处理这个是肯定毋庸置疑的(这是针对单对象),但是我们的事务不是只针对一个对象做一件事,扣完仓库还要去做别的也许是根据当前库存去做校验公式计算,在把计算结果保存到另一个对象(但是如果在计算另一个对象的时候出错,扣掉的库存该如何处理?)。

2011-11-04 22:11

2011年11月04日 22:04 "@gamex"的内容
1)event1进入队列后,把event2放入队列;(计划任务)
2)event1进入队列后,待event1执行后才放入event2;(一件事完了才会有第二件事)
...

你说的是不是大事件,例如:转账就是个大事件,然后排队处理?

2011-11-05 07:50

2011年11月04日 22:11 "@gamex"的内容
A 线程 处理一个事务(里面会用到仓库对象)如果失败需要回滚 如果成功store event to disk ...


这里假设前提需要事务,然后再用Event Sourcing,这实际是矛盾的,因为事务是串行,事件是并行的,两者本质上是矛盾的,水和火。

在实际上,我们是缩小需要使用事务的范围,绝不将事务和并发混合。这样才能提供整体性能。

如果实际中有这种极端的实例,可以通过避免在一个内存中的这种线程Queue模式,转化为JMS的分布式事务来实现。也就是说,如果有楼主这个需求,又要求使用事件,又要求事务安全,那么不要使用线程来做,而是利用Disruptor这样Queue机制转发到JMS中,使用JMS这种异步的分布式事务来实现即可。

见这个讨论:事件与事务
[该贴被banq于2011-11-05 08:04修改过]

8Go 1 2 3 4 ... 8 下一页

赞助商链接

赞助商链接

返回顶部

移动版 关于本站 使用帮助 联系反馈 最佳分辨率1366x768
OpenSource JIVEJDON Powered by JdonFramework Code © 2002-20 jdon.com