1

次のColdfusionプロセスがあります。

  1. 私のコードは、proc CommentInsertをデータベースで呼び出します(これにより、コメントが挿入され、追加されるコメントについてEventInsertと呼ばれるイベント挿入procが呼び出されます)

  2. 次に、Event.GetEventByCommentId(commentId)を呼び出します

手順1でCommentInsertによってトリガーされたイベントレコードの追加がEventInsertで完了していないため、結果はレコードが返されません。

ステップ1と2の間に遅延を作成すると、ステップ2でレコードセットが返されるため、これが当てはまることがわかります。

これにより、ステップ1でイベント挿入がコミットされる前に、ステップ2での読み取りが速すぎると思います。

私の質問は、Coldfusionプロセスに、ステップ1が完了するまで待ってから、ステップ2で読み取りを行うように指示するにはどうすればよいですか?

ステップ1とステップ2は、完全に別個の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が呼び出されたときに有効なレコードが返されます。

だから私の質問は、ループを使用せずにこれを防ぐにはどうすればよいですか?

更新:使用される2つのストアドプロシージャは次のとおりです。

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プロシージャで呼び出されたMySql Now()関数は、クエリで使用されているColdfusion #Now()#よりもわずかに遅れていました。したがって、コード行はそのレコードを除外しました。また、コメントがすばやく追加されたときにのみ発生したのはなぜですか。

なんてビッチ。皆様からのご意見ありがとうございました。

于 2011-03-04T18:36:23.997 に答える
0

これをまっすぐにしましょう:あなたは挿入を行うMySQL SPを呼び出し、次に別のSPを呼び出して別の挿入を行います。これら2つの間にColdFusionに戻ることはありませんか?そうですか?

その場合は、SPが値を正しく返さないという問題があるか、結果を間違った場所で探している可能性があります。

私はMySQLSPに問題があることにもっと傾いています。それらは必ずしも優れているわけではなく、パフォーマンス上の大きなメリットはありません。ビューは便利ですが、SPは率直に言って少しごみです。最初のSP内から2番目のSPを呼び出して値を返すと、元のSPからColdFusionに正しく戻されないため、結果が得られないのではないかと思います。

正直なところ、適切なDAOまたはサービスに2つのORM関数または単純なcfqueriesを記述して、最初にコメントを挿入した結果を記録し、値を返すことをお勧めします。その値を返したら、関数をもう1回呼び出して、返されたコメントIDに基づいてイベントを取得します。(ColdFusion 8はGenerated_Keyを提供し、ColdFusion 9はgeneratedkeyを生成します。これがRailoに何になるかはわかりませんが、「result」属性構造に含まれます)。

考えてみると、入力したばかりのコメントに基づいてイベントを取得している理由すらわかりません。イベントに対してそのコメントを追加したので、コメントを介して家の中を移動することなく、完全なイベントレコード/オブジェクトを取得できるIDであっても、そのイベントに関するデータがすでにあるはずです。 。

したがって、全体として、一歩下がって、作業しているデータフローを確認し、おそらくリファクタリングすることをお勧めします。

于 2011-02-24T23:46:49.903 に答える