我有一個產生MySQL查詢會是這個樣子PHP腳本:PDO,多條語句,和比賽條件
INSERT INTO `dailydb`.`probact_actionstaken`(`dispatcher`) VALUES ('kryan');
SET @actionTakenId = LAST_INSERT_ID();
INSERT INTO `dailydb`.`probact_actionstaken_types`(`actionTaken`,`type`)
VALUES
(@actionTakenId, 2);
INSERT INTO `dailydb`.`probact_actionstaken_problems`(`actionTaken`,`problem`)
VALUES
(@actionTakenId, 2);
INSERT INTO `dailydb`.`probact_actionstaken_actions`(`actionTaken`,`action`)
VALUES
(@actionTakenId, 3);
INSERT INTO `dailydb`.`probact_actionstaken_text`(`actionTaken`,`input`,`value`)
VALUES
(@actionTakenId, 3, '7576'),
(@actionTakenId, 4, 'B61'),
(@actionTakenId, 5, '4'),
(@actionTakenId, 6, 'kryan'),
(@actionTakenId, 7, 'test'),
(@actionTakenId, 8, 'testing new debug');
SELECT `index`, `timestamp`
FROM `dailydb`.`probact_actionstaken`
WHERE `index`[email protected];
(請注意,顯示此查詢的目的,所有值都手動搜索和替換上:someId
與相應的值,因爲我’使用米準備的語句)
(還注意到,probact_actionstaken
。index
是一個自動遞增主鍵,probact_actionstaken
。timestamp
默認爲的結果)
該查詢的目標是插入大量的相關數據(基於自動值probact_actionstaken
。 index
存儲在@actionTakenId
中),然後返回自動生成的index
和timestamp
以供使用(該腳本在使用此輸出的AJAX調用中調用)。
該查詢大部分執行正確:五個INSERT
語句都將正確的值插入到數據庫中。我的問題是最後的SELECT
聲明。我嘗試去通過與下面的PHP代碼查詢結果:
$statement = $dbh->prepare($query);
$statement->execute($params);
$output['results'] = array();
do
{
$output['results'][] = array();
while ($result = $statement->fetch(PDO::FETCH_ASSOC))
{
$output['results'][count($output['results'])-1][] = $result;
if (isset($result['index']))
{
$output['index'] = intval($result['index']);
}
if (isset($result['timestamp']))
{
$output['timestamp'] = $result['timestamp'];
}
}
} while ($statement->nextRowset());
echo json_encode($output);
的想法是使用do...while
塊通過從INSERT
語句的結果得到的,然後得到的那最後SELECT
結果聲明,它存儲在我的$output
中。
在我的本地機器上(運行PHP 5.4.4),這很好地工作。在具有PHP 5.3.10的服務器上,$statement->nextRowset()
每次都返回false,所以我只得到第一個行集(因爲它的語句爲INSERT
,它爲’)。請注意,實際插入無論正確工作,並且當我在phpMyAdmin ’的SQL功能中運行上述手動填充的查詢時,它將返回正確的結果(由插入的索引和時間戳組成的表)。
閱讀了解這些問題後,似乎這樣的多個語句是一個糟糕的主意,並且實際上,它們與真實的預處理語句一起工作,而我仍然使用默認的模擬預處理語句。所以我可以切換到$dbh->prepare
和$statement->execute
的單獨電話,這將解決我的問題,但我’米擔心競爭條件。服務器使用Nginx,許多用戶可能同時輸入條目。我不想’ t要LAST_INSERT_ID()
返回其他用戶’的條目,並將這些字段與錯誤的操作相關聯。
在MySQL或PHP內部是否有某些原因可以防止競態條件問題?我可以採取一些措施?還是有安全的方式來使用多個預處理語句?如果後者,它在PHP 3.5.10中工作嗎?
很高興聽到我在比賽場地上一無所知。我會將它切換到單個語句。我會在幾分鐘內讓你檢查你是否接受,因爲這看起來相當清晰,而且不太可能有另一個答案最好。 – KRyan