内存中事件溯源算法 - 对吗?它是线程安全的吗?
对于这个问题的轻微推测性质表示歉意。
我正在使用内存中的静态对象编写一个 Cms 来保存系统的当前状态,并使用事件源创建一个事件日志,我可以用它来重建对象状态,并提供回滚等(请参阅http://martinfowler.com/articles/lmax.html 如果你不知道我是什么关于)
public class Cms
{
private static object WriteLock = new object();
public static Cms Read { get; set; }
static Cms Write { get; set; }
static Cms()
{
Read = RebuildFromActionLog();
Write = RebuildFromActionLog();
}
public static void Update(Action action)
{
lock (WriteLock)
{
try
{
action.Apply(Write);
}
catch(Exception ex)
{
Write = RebuildFromActionLog(); //ditch the potentially messed up Write model
throw;
}
LogAction(action); //the action was a keeper, so keep it
Read = Write; //ditch the current read only model - it will continue to be used by any requests that have grabbed it
Write = RebuildFromActionLog(); //get a new model ready for the next write
}
}
...
}
除了潜力如果执行或重建需要很长时间,并且可能会使用大量内存,则大量写入会堆积起来,这是否存在任何错误,特别是与并发相关的错误?
Apologies for the slightly speculative nature of this question.
I am writing a Cms using an in-memory static object to hold the current state of the system, and am using Event Sourcing to create an event log which I can use to rebuild the object state, and to provide roll back etc. (see http://martinfowler.com/articles/lmax.html if you have no idea what I am on about)
public class Cms
{
private static object WriteLock = new object();
public static Cms Read { get; set; }
static Cms Write { get; set; }
static Cms()
{
Read = RebuildFromActionLog();
Write = RebuildFromActionLog();
}
public static void Update(Action action)
{
lock (WriteLock)
{
try
{
action.Apply(Write);
}
catch(Exception ex)
{
Write = RebuildFromActionLog(); //ditch the potentially messed up Write model
throw;
}
LogAction(action); //the action was a keeper, so keep it
Read = Write; //ditch the current read only model - it will continue to be used by any requests that have grabbed it
Write = RebuildFromActionLog(); //get a new model ready for the next write
}
}
...
}
Aside from the potential for lots of writes to stack up if execution or rebuilding takes a long time, and the potential for lots of memory to be used, are there any bugs in this, particularly concurrency related bugs?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果有人使用
Read
的公共 getter 或 setter,您可能会遇到问题,因为您在那里没有同步。如果有人在另一个线程在Update
中修改该属性的同时使用该属性,则读取可能会获取过时的值,或者写入所做的更改可能会默默丢失。该财产真的需要公开吗?并且公开可写?
You may have a problem if someone uses the public getter or setter of
Read
, as you have no synchronization there. If someone uses that property at the same time as another thread modifies it inUpdate
the read could fetch a stale value, or a change made by writing could be silently lost.Does that property really need to be public? And publicly writeable?