Coldfusion 服务器结构中存在null错误

Coldfusion 服务器结构中存在null错误,coldfusion,null,runtime-error,structure,Coldfusion,Null,Runtime Error,Structure,我有一个服务器变量,一个由结构组成的结构,所有用户都可以高度访问它(并发)。值的添加和删除非常频繁。下面是我的服务器变量的一个小示例。真实的一个有更多的数据 <cfset SERVER.structure = StructNew()> <cfset s = StructNew()> <cfset StructInsert(s, 'test11', 'value11', true)> <cfset StructInsert(s, 'test12', 'v

我有一个服务器变量,一个由结构组成的结构,所有用户都可以高度访问它(并发)。值的添加和删除非常频繁。下面是我的服务器变量的一个小示例。真实的一个有更多的数据

<cfset SERVER.structure = StructNew()>

<cfset s = StructNew()>
<cfset StructInsert(s, 'test11', 'value11', true)>
<cfset StructInsert(s, 'test12', 'value12', true)>
<cfset StructInsert(SERVER.structure, 'test1', s, true)>

<cfset s = StructNew()>
<cfset StructInsert(s, 'test21', 'value21', true)>
<cfset StructInsert(s, 'test22', 'value22', true)>
<cfset StructInsert(SERVER.structure, 'test2', s, true)>

每隔几个小时,我循环这个结构来清理过期的数据。但是,我在循环变量时遇到错误“null null”,如下所示:

<cfloop collection="#SERVER.structure#" item="key">
    <cfif StructKeyExists(SERVER.structure, key)>
        <cfloop collection="#StructFind(SERVER.structure, key)#" item="key2">
            <!--- And some code here --->
        </cfloop>
    </cfif>

    <cfif StructCount(StructFind(SERVER.structure, key)) eq 0>
        <cfset StructDelete(SERVER.structure, key, false)>
    </cfif>
</cfloop>

我收到了示例第一行中的错误。在这一行中,确切地说:

<cfloop collection="#SERVER.structure#" item="key">

所以我尝试了另一种方法。我没有一个接一个地循环,而是创建了一个密钥数组并循环它。不幸的是,“null-null”错误也发生在这一行:

<cfset arrayOfKeys = StructKeyArray(SERVER.structure)>

我的第一个理论是ColdFusion无法处理这个服务器变量所具有的并发级别。我试图在这里使用
,同时清除变量,但也不起作用。我不能让这个
变量被用户实际使用和修改,因为它会增加额外的负载(我相信)

我不知道。。。我没有主意了。现在有人知道为什么会发生这种情况,或者以前遇到过这种问题吗?对于这个问题的解决方案或解决方法,甚至是改进我的代码的建议,也将非常受欢迎

多谢各位

我试图在这里使用
,同时清除变量,但是 也不管用。我不能让这个
变量 由于额外的负载,用户实际上正在使用和修改 (我相信)它会增加

这是你的问题。如果您正在使用服务器作用域,则必须锁定对它的所有访问(读和写)。否则,您将得到错误。这是长话短说

我的第一个理论是ColdFusion无法处理这个服务器变量所具有的并发级别

不,ColdFusion将把单个操作同步到服务器范围(它是在Java级别处理的),这就是它的工作开始和结束的地方。只是你的方法无法处理它。也就是说,您不需要在自己的代码中采取措施来缓解竞争条件。你的这一主张:

使用变量时,我没有锁定访问权限,因为不会发生冲突

这完全是错误的。在你的循环中有一个竞赛条件

正如其他人所暗示的,这是非常糟糕的应用程序体系结构,代码也很简单

只需将数据放入数据库。这就是数据库的用途,它们的编写方式可以优化您试图(但显然没有成功)实现的操作类型

我认为这可能是一种过早优化的情况:您是否在一个适当配置和设计的数据库中拥有这些数据?还是你在猜测这会是个问题?我怀疑是后者。或者数据库服务器未正确配置

除了数据库层之外,您还可以像其他人建议的那样使用缓存层

但不要像其他人所说的那样重新发明轮子


对您的问题的底线回答是,您之所以会出现错误,是因为您没有正确锁定数据,并且代码中存在竞争条件,使得ColdFusion尝试访问您告知存在的数据,但随后可能已被更改。这是由于您的代码造成的,而不是ColdFusion中的缺陷。

首先,您是否锁定了对该变量的访问?否则,可能会由于并发读/写访问而导致问题。其次,听起来您可以通过替换整个结构或使用其副本来减少并发问题。想法是在“副本”上进行所有更改。完成后,替换服务器范围内的整个结构(在锁中)。一百万行太多了-为什么不将数据存储在数据库中?因此,人们不必编写潜在的简单查询,而必须浏览结构的结构?听起来很难。你在这里试图做的是重新发明一些已经存在的东西;更具体地说,它有多个成熟的、经过良好测试的、许可的软件解决方案——因此,与其在调试上浪费时间,不如选择其中一个可行的解决方案(p.s.XML是一个可怕的建议,任何人如果不这样想,应该立即从最近的砖墙寻求纠正治疗)插入或删除数据时,我没有收到错误。我只是在循环或获取示例的SERVER.structure变量的密钥时收到错误。每个用户将在其密钥中添加新条目,以便用户无法覆盖其他用户的数据。用户可以在密钥中覆盖自己的数据,是的,但是对于这个简单的功能来说,这不是问题。永远不会删除SERVER.structure变量的键。将添加新密钥,但不会删除。这就是我不明白的。如果它们总是在那里,为什么我不能列出/循环它们?>“每隔几个小时,我循环这个结构来清理过期的数据。”如果用户在清理数据时试图访问这些数据,会发生什么?但是,[耸耸肩],一个统一的唱诗班告诉你,你的方法很差。真的,没什么好说的了。ColdFusion函数StructKeyArray()不会删除任何内容,它也会给我同样的错误,所以。。。你告诉我我的方法很差,但你没有证明你的观点是正确的。如果你告诉我它很差,因为一个结构是一个Map java对象,而这个数据类型不是线程安全的,例如,它是一个hashmap,即使没有数据被删除,竞争条件也存在,例如,当hashmap被重新刷新时,我会理解它,我会认为问题已经解决。如果我不得不说“好”,我不会用它,因为