Coldfusion CFLOCK:使用什么范围?

Coldfusion CFLOCK:使用什么范围?,coldfusion,coldfusion-2016,Coldfusion,Coldfusion 2016,我有一个为下一个事件生成令牌的函数。我们称之为eventID。这是数字,但由于业务原因存储为varchar。可以从应用程序中的多个位置调用此函数,为了避免竞争条件,为了避免为不同的用户生成相同的ID,添加了应用程序范围锁。但在少数情况下,为两个不同的事件生成相同的ID <cffunction name="getEventID" returntype="string"> <cfset var newID = ""> <cflock scope="Applica

我有一个为下一个事件生成令牌的函数。我们称之为eventID。这是数字,但由于业务原因存储为varchar。可以从应用程序中的多个位置调用此函数,为了避免竞争条件,为了避免为不同的用户生成相同的ID,添加了应用程序范围锁。但在少数情况下,为两个不同的事件生成相同的ID

<cffunction name="getEventID" returntype="string">
  <cfset var newID = "">
  <cflock scope="Application" timeout="5" throwontimeout="true">
   <cfquery name="qry" datasource="#DSN#">
     SELECT TOP 1 CONVERT(int, eventID) AS eventID
     FROM events WHERE ISNUMERIC(eventID) = 1
     ORDER BY CONVERT(int, eventID) DESC  
   </cfquery>
  <cfset newID = qry.eventID + 1>
 </cflock>
<cfreturn newID>
</cffunction>

选择TOP 1转换(int,eventID)作为eventID
来自ISNUMERIC(eventID)=1的事件
按转换顺序(int,eventID)描述

CFLOCK的实现是否有问题?

根据您的查询,它似乎试图从数据库中访问最新的ID,但我不知道这如何保证每次调用时都有唯一的值。首先,我将使用命名锁而不是范围锁。第二,你需要更新这个锁中的DB,否则其他线程可能会在更新之前调用此代码,并可能获得相同的id。@Redtopia,你可能在引导我找到一些东西。你的意思是如果我不更新数据库,只是读取它,另一个线程可以读取并获得相同的ID吗?@CFML\u Developer是的。。。确切地创建下一个ID后,更新数据库。这将是线程安全的。但是有更好的方法来做到这一点。。。也许你受到其他因素的限制。你可以让DB在insert上生成ID。我会让DB完成这项工作。您的函数仅获取最近插入的ID并添加1。您的代码完全可以选择一个ID,而另一个ID可以选择相同的ID,特别是因为您还没有使用
newID
执行任何操作。如果您检查
eventID
是否为数字,然后尝试
convert()
将其转换为
int
,我不确定您会有什么业务需求。这很容易引发错误或返回意外结果。TSQL的
isNumeric()。它仍然会将“
+
”视为
数字