内存中事件溯源算法 - 对吗?它是线程安全的吗?

发布于 2024-12-10 00:44:19 字数 1256 浏览 1 评论 0原文

对于这个问题的轻微推测性质表示歉意。

我正在使用内存中的静态对象编写一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

两个我 2024-12-17 00:44:19

如果有人使用 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 in Update 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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文