我有一个SERVER变量,一个结构结构,所有用户都高度访问(并发)。非常频繁地添加和删除值。这是我的SERVER变量的一个小例子。真正的数据有更多的数据。
<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无法处理此SERVER变量所具有的并发级别。我在这里尝试使用<cflock>
,同时清除变量,但它也没有用。我不能让这个<cflock>
变量实际被用户使用和修改,因为它会增加额外的负载(我相信)。
我不知道......我没有想法。现在有人为什么会发生这种情况或之前遇到过这个问题?此问题的解决方案或解决方案,甚至是使我的代码更好的建议,也非常受欢迎。
非常感谢。
答案 0 :(得分:1)
我尝试在这里使用
<cflock>
,同时清除变量,但它 也没用。我不能将<cflock>
放在变量所在的位置 由于额外的负载,用户实际上正在使用和修改 它会添加(我相信)。
这是你的问题。如果您使用的是服务器范围,则必须锁定对它的所有访问权限(读取和写入)。否则你会收到错误。这就是它的长短。
好吧:不。 ColdFusion会将各个操作同步到服务器范围(好吧:它在Java级别处理),这就是它的工作开始和结束的地方。只是你的方法无法处理它。也就是说,您没有采取措施来缓解您自己的代码中的竞争条件。你的这个主张:我的第一个理论是ColdFusion无法处理此SERVER变量具有的并发级别
我在处理变量时没有锁定访问权限,因为碰撞不会发生
是错的。你的循环中存在竞争条件。
正如其他人所暗示的那样,这是一个非常糟糕的应用程序架构,代码很容易。
只需将数据放入数据库即可。这就是数据库的用途,它们的编写方式可以优化您正在尝试的各种操作(但显然不是成功)。
我认为这可能是过早优化的情况:您是否在正确配置和设计的数据库中拥有此数据?或者你是第二次猜测这将是一个问题?我怀疑是后者。或者没有正确配置数据库服务器。
除了数据库层之外,您还可以像其他人建议的那样使用缓存层。
但就像其他人所说的那样,不要重新发明轮子。
您的问题的底线答案是您收到错误,因为您没有正确锁定数据,并且您的代码中存在竞争条件,使ColdFusion尝试访问您告诉它的数据,但随后可以改变。这是由于您的代码,而不是ColdFusion中的缺点。