我在cfwheels中遇到了一些并发问题。
我在每次用户请求某事时正在执行的events / onrequeststart.cfm中都有一些代码。
测试用例: 用户A - 请求时间:10秒 用户B - 请求时间:2秒
如果用户B在用户A正在处理请求时发出请求,则用户B的设置将进入用户A,用户A将根据用户的B请求显示结果。 / p>
我尝试在onrequeststart.cfm上使用cflock,但它似乎不起作用。我对cfwheels没有多少经验,所以我可能会尝试做一些逻辑上错误的事情。
这是混淆代码的一部分。
<cfquery name="currentUser" datasource="#application.ds#">
select * from clientadmin where clientAdminid ='#session.clientadminid#'
</cfquery>
<cfquery name="currentClient" datasource="#application.ds#">
select * from clientBrands where clientbrandID ='#currentUser.ClientBrandID#'
</cfquery>
<cfset application.clientAdminSurveys = application.generalFunctions.clientSurveys(clientAdminID=session.clientAdminID, clientBrandID = currentUser.clientBrandID)>
<cfset application.AssociatedDoctors = application.generalFunctions.AssociatedDoctors(clientAdminID=session.clientAdminID, clientBrandID = currentUser.clientBrandID)>
所以,我想我的问题是,如何避免这种情况发生?
答案 0 :(得分:6)
1)应用程序范围是“应用程序范围”(站点范围内的所有用户) - 您不应该在那里设置每个用户设置,就像您发现的那样,用户B覆盖用户A.使用会话每个用户的范围。因此,在最后两行中,您将使用会话范围数据设置应用程序范围内容!
2)作为旁注,在轮子中你可以使用application.wheels.datasourcename来获取数据库名称
答案 1 :(得分:0)
我会将该代码放入控制器内的一个函数(controller.cfc
)并使用过滤器运行它。
请参阅:http://cfwheels.org/docs/1-1/chapter/filters
对我来说这对于类似的任务没有任何问题。
此外,我会删除对application.
的任何引用,因为这可能是项目混淆的地方。放置这些功能的正确位置是events/functions.cfm
当然这没有看到更多的代码...
答案 2 :(得分:0)
正如Neokoenig所提到的,您正在利用共享范围来存储用户特定数据,您应该将其存储在SESSION中。如果您需要应用程序范围内的数据,则应该在设置该数据时使用锁定,但看起来您应该在onSessionStart中运行一次,而不是在每个请求上运行。如果您需要在每个请求上运行它,您可能希望继续使用onRequestStart但使用特定于用户的会话存储而不是全局应用程序层。
请记住: 应用程序变量将为所有用户显示相同的数据。因此,如果用户a设置application.foo = 1而用户b设置application.foo = 2,则用户1尝试访问application.foo,用户1将看到用户2的值为2.如果这是使用会话范围你不会有同样的问题。如果用户1设置SESSION.foo = 1并且用户2设置SESSION.foo = 2.当用户访问SESSION.foo变量时,它将仅包含该用户设置的数据(例如:用户1将输出SESSION.foo并查看价值,1)