1

我有以下冷融合过程:

  1. 我的代码对 proc CommentInsert 进行了数据库调用(这会插入一条评论,然后调用一个事件插入 proc 关于正在添加的名为 EventInsert 的评论)

  2. 然后我调用 Event.GetEventByCommentId(commentId)

结果是没有返回记录,因为 EventInsert 还没有完成添加第 1 步中由 CommentInsert 触发的事件记录。

我知道是这种情况,因为如果我在第 1 步和第 2 步之间创建延迟,则在第 2 步中返回一个记录集。

这让我相信,在步骤 1 中的事件插入提交之前,步骤 2 中的读取发生得太快了。

我的问题是,如何告诉 Coldfusion 进程等到第 1 步完成后再进行第 2 步中的读取?

第一步和第二步是两个完全不同的方法。

代码:

<cfset MessageHandlerManager = AddComment(argumentCollection=arguments) />

<cfset qEvents = application.API.EventManager.GetEventFeed(commentId=MessageHandlerManager.GetReturnItems()) />

另外,让我补充一点,传递的 commentId 是有效的。我检查过。

另一种看待它的方式:

鉴于此代码:

<!--- Calls CommentInsert proc, which inserts a comment AND inserts an
event record by calling EventInsert within the proc --->
<cfset var newCommentId = AddComment(argumentCollection=arguments) />

<cfloop from="1" to="1000000" index="i">
</cfloop>

<!--- Gets the event record inserted in the code above --->
<cfset qEvent =
application.API.EventManager.GetEventFeed(commentId=newCommentId ) />

当我运行上面的代码时,qEvent 会返回一个有效的记录。但是,当我注释掉循环时,记录又是空的。

我认为正在发生的事情是 CommentInsert 返回新的评论 Id,但是当调用 GetEventFeed 函数时,EventInsert proc 没有及时完成并且没有找到记录。

因此,通过添加循环并延迟一点,事件插入有时间完成,然后在调用 GetEventFeed 时返回有效记录。

所以我的问题是,如何在不使用循环的情况下防止这种情况发生。

更新:这是使用的两个存储过程:

DELIMITER $$

DROP PROCEDURE IF EXISTS `CommentInsert` $$
CREATE DEFINER=`root`@`%` PROCEDURE `CommentInsert`(
        IN _commentParentId bigint,
        IN _commentObjectType int,
        IN _commentObjectId bigint,
        IN _commentText text,
        IN _commentAuthorName varchar(100),
        IN _commentAuthorEmail varchar(255),
        IN _commentAuthorWebsite varchar(512),
        IN _commentSubscribe tinyint(1),
        IN _commentIsDisabled tinyint(1),
        IN _commentIsActive tinyint(1),
        IN _commentCSI int,
        IN _commentCSD datetime,
        IN _commentUSI int,
        IN _commentUSD datetime,
        OUT _commentIdOut bigint
    )
BEGIN


    DECLARE _commentId bigint default 0;

    INSERT INTO comment
            (
            commentParentId,
            commentObjectType,
            commentObjectId,
            commentText,
            commentAuthorName,
            commentAuthorEmail,
            commentAuthorWebsite,
            commentSubscribe,
            commentIsDisabled,
            commentIsActive,
            commentCSI,
            commentCSD,
            commentUSI,
            commentUSD
            )
        VALUES
            (
            _commentParentId,
            _commentObjectType,
            _commentObjectId,
            _commentText,
            _commentAuthorName,
            _commentAuthorEmail,
            _commentAuthorWebsite,
            _commentSubscribe,
            _commentIsDisabled,
            _commentIsActive,
            _commentCSI,
            _commentCSD,
            _commentUSI,
            _commentUSD
            );



    SET _commentId = LAST_INSERT_ID();


    CALL EventInsert(6, Now(), _commentId, _commentObjectType, _commentObjectId, null, null, 'Comment Added', 1, _commentCSI, Now(), _commentUSI, Now());



    SELECT _commentId INTO _commentIdOut ;

    END $$

DELIMITER ;


DELIMITER $$

DROP PROCEDURE IF EXISTS `EventInsert` $$
CREATE DEFINER=`root`@`%` PROCEDURE `EventInsert`(
        IN _eventTypeId int,
        IN _eventCreateDate datetime,
        IN _eventObjectId bigint,
        IN _eventAffectedObjectType1 int,
        IN _eventAffectedObjectId1 bigint,
        IN _eventAffectedObjectType2 int,
        IN _eventAffectedObjectId2 bigint,
    IN _eventText varchar(1024),
        IN _eventIsActive tinyint,
        IN _eventCSI int,
        IN _eventCSD datetime,
        IN _eventUSI int,
        IN _eventUSD datetime

    )
BEGIN

        INSERT INTO event
            (
            eventTypeId,
            eventCreateDate,
            eventObjectId,
            eventAffectedObjectType1,
            eventAffectedObjectId1,
            eventAffectedObjectType2,
            eventAffectedObjectId2,
      eventText,
            eventIsActive,
            eventCSI,
            eventCSD,
            eventUSI,
            eventUSD
            )
        VALUES
            (
            _eventTypeId,
            _eventCreateDate,
            _eventObjectId,
            _eventAffectedObjectType1,
            _eventAffectedObjectId1,
            _eventAffectedObjectType2,
            _eventAffectedObjectId2,
      _eventText,
            _eventIsActive,
            _eventCSI,
            _eventCSD,
            _eventUSI,
            _eventUSD
            );


    END $$

DELIMITER ;
4

2 回答 2

1

找到了。归结为 EventManager.GetEventFeed 查询中的这一行:

AND eventCreateDate <= <cfqueryparam cfsqltype="cf_sql_timestamp" value="#Now()#" />

发生的事情是 EventInsert proc 中调用的 MySql Now() 函数比查询中使用的 Coldfusion #Now()# 晚了一小部分。因此,该行代码排除了该记录。此外,为什么只有在快速添加评论时才会发生这种情况。

真是个混蛋。感谢大家的意见和建议。

于 2011-03-04T18:36:23.997 回答
0

让我直截了当地说:你调用一个 MySQL SP,它执行一个插入,然后调用另一个 SP 来执行另一个插入。这两者之间没有回归ColdFusion?那正确吗?

如果是这种情况,那么很可能是您的 SP 没有正确返回值存在问题,或者您在错误的位置寻找结果。

我更倾向于 MySQL SP 存在问题。它们并不完全好,并没有真正给您带来很多性能优势。视图很有用,但坦率地说,SP 有点垃圾。我怀疑当您从第一个 SP 中调用第二个 SP 并返回一个值时,它没有正确地从原始 SP 传回 ColdFusion,因此缺少结果。

老实说,我的建议是在合适的 DAO 或服务中编写两个 ORM 函数或简单的 cfqueries 来记录插入评论的结果并返回一个值。返回该值后,对函数进行另一个调用以根据返回的评论 ID 获取您的事件。(ColdFusion 8 会给你 Generated_Key,ColdFusion 9 是 generatekey,我不确定它在 Railo 中会是什么,但它会在“结果”属性结构中出现)。

考虑一下,我什至不确定您为什么会根据刚刚输入的 commentid 来获取事件。您刚刚针对某个事件添加了该评论,因此您应该已经拥有有关该事件的一些数据,即使它只是您可以从中获取完整事件记录/对象的 ID,而无需通过评论四处走动.

所以总的来说,我建议退后一步,看看你正在使用的数据流,也许还可以重构它。

于 2011-02-24T23:46:49.903 回答