Фиксация базы данных недостаточно быстра для процесса Coldfusion
У меня есть следующий процесс Coldfusion:
Мой код делает вызов базы данных для proc CommentInsert (это вставляет комментарий, а затем вызывает proc вставки события для добавляемого комментария под названием EventInsert)
Затем я вызываю Event.GetEventByCommentId(commentId)
В результате записи не возвращаются, так как EventInsert не завершил добавление записи события, вызванной CommentInsert на шаге 1.
Я знаю, что это так, потому что если я создаю задержку между шагами 1 и 2, то набор записей возвращается на шаге 2.
Это заставляет меня поверить, что чтение на шаге 2 происходит слишком быстро, до того как вставка события зафиксирована на шаге 1.
Мой вопрос: как заставить процесс 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 возвращает новый идентификатор комментария, но когда вызывается функция GetEventFeed, процесс EventInsert не завершился вовремя, и запись не была найдена.
Таким образом, добавляя цикл и немного задерживая, вставка события успевает завершиться, и затем при вызове 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 ;
2 ответа
Нашел это. Сводится к этой строке в запросе EventManager.GetEventFeed:
AND eventCreateDate <= <cfqueryparam cfsqltype="cf_sql_timestamp" value="#Now()#" />
То, что происходило, было функцией MySql Now(), вызванной в процедуре EventInsert, на долю позже, чем Coldfusion #Now()#, использованный в запросе. Поэтому строка кода исключает эту запись. Кроме того, почему это происходит только тогда, когда комментарии добавляются быстро.
Что за бичи Благодарность за вклад каждого.
Позвольте мне сказать прямо: вы вызываете MySQL SP, который выполняет вставку, которая затем вызывает другого SP, чтобы выполнить другую вставку. Там нет возврата к ColdFusion между этими двумя? Это правильно?
Если это так, то, скорее всего, проблема в том, что ваш SP неправильно возвращает значения или вы ищете неправильный результат для результата.
Я более склонен к проблеме с MySQL SP. Они не очень хороши и на самом деле не дают вам большого выигрыша в производительности. Мнения полезны, но SP, честно говоря, немного мусор. Я подозреваю, что когда вы вызываете второй SP из первого SP, и он возвращает значение, оно неправильно передается обратно из исходного SP в ColdFusion, отсюда и отсутствие результата.
Если честно, я бы предложил написать две функции ORM или простые cfqueries в подходящем DAO или сервисе, чтобы сначала записать результат вставки комментария и вернуть значение. Вернув это значение, сделайте другой вызов функции, чтобы получить ваше событие на основе возвращенного идентификатора комментария. (ColdFusion 8 даст вам Generated_Key, ColdFusion 9 - генерируемый ключ, я не уверен, что это будет в Railo, но он будет там в структуре атрибута "result").
Размышляя об этом, я даже не уверен, почему вы получаете событие на основании только что введенного комментария. Вы только что добавили этот комментарий к событию, поэтому у вас уже должны быть какие-то данные об этом событии, даже если это просто идентификатор, по которому вы можете получить полную запись / объект события без необходимости обходить дом с помощью комментария.,
В общем, я бы предложил сделать шаг назад и посмотреть на поток данных, с которым вы работаете, и, возможно, провести его рефакторинг.