【问题标题】:Database commit not quick enough for Coldfusion processColdfusion 进程的数据库提交速度不够快
【发布时间】:2011-03-05 02:36:23
【问题描述】:

我有以下Coldfusion过程:

  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 ;

【问题讨论】:

  • 你是否在不同的线程中运行这两个命令?
  • 邮政编码以获得有用的答案。
  • 我们还需要了解更多信息。 1. 你用的是什么数据库? 2. AddComment() 内部发生了什么?您是否使用 cfthread,您是否在数据库级别进行异步处理? 3. 怎么可能找回了有效身份证,却没有记录? AddComment 返回的 ID 是怎样的? 4. 您是否使用了任何类型的缓存,尤其是在 GetEventFeed 内部?
  • (1) MySQL (2) 调用存储过程,CommentInsert (3) 我得到一个 COMMENT ID,用于检索 EVENT 记录。那条记录是空白的。我的第一篇文章清楚地解释了 CommentInsert 过程调用 EventInsert 过程。 Id 通过调用 MessageHandlerManager.GetReturnItems() 返回,如代码所示。 (4) 无缓存。只是一个标准的 cfquery。
  • 你能把GetEventFeed()的代码贴出来吗?

标签: coldfusion railo


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

    让我直截了当: 您调用一个 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,而无需通过评论四处走动.

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

    【讨论】:

    • 对不起,斯蒂芬,但我不相信再造是答案。如果有问题,那么我想在打电话之前确切地知道它是什么。就像我在原始帖子中所说的那样,如果我在两个 cfset 语句之间添加一个循环(例如 1 到 10000000),则该过程每次都有效。所以这绝对是时间问题。如果 SP 没有正确返回值,它将不考虑循环。
    • 我还更新了原始帖子,提供了可能有帮助的附加说明。
    • 幽默吧。在 addComment 函数中执行一个简单的 cfquery 来插入您的评论并使用 cfquery 的结果来获取新的 id。基本上我希望你证明问题出在或不在于对存储过程的调用。
    • 好的,试一试。与此同时,我已经发布了存储的过程。谢谢
    • 该死的。它现在已经停止做这个问题,所以我无法测试你的理论。有趣,因为在我的开发人员遇到这个问题之前,我的现场站点很好。现在突然之间,我的开发人员很好,我的生活也在这样做。在这两种环境中都没有代码更改。我难住了。我无法在实时站点上摆弄,所以我只需要等待,看看它是否会在 dev 中返回,然后再解决它。多么痛苦!
    猜你喜欢
    • 1970-01-01
    • 2020-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-16
    • 2012-10-17
    • 1970-01-01
    • 2011-12-15
    相关资源
    最近更新 更多