2 つのアプリケーションがストアド プロシージャを呼び出した場合、タスクを実行するためにコードのセクションにアクセスできるのは 1 つだけであり、他のアプリケーションは最初のアプリケーションまでブロックされるように、同期する必要があるタスクを実行するストアド プロシージャがmysqlにあります。 1つはタスクを完了します。
DELIMITER $$
CREATE PROCEDURE SP_GEN_ID(IN NAME VARCHAR(20))
BEGIN
DECLARE maxLen int default 0;
START TRANSACTION;
#the section of code that needs to be synchronized
COMMIT
END;
$$
DELIMITER ;
そのため、2 つのアプリケーションがストアド プロシージャを同時に呼び出す場合は、タスクを同期する必要があります。
を。しかし、 START TRANSACTIONとCOMMITは実行を同期しませんでした。
b. また、LOCK TABLES tableAをストアド プロシージャで使用して同期を確保することもできません。
c. アプリケーション レベルでストアド プロシージャ コールを同期しようとしました。使った
boost_interprocess scoped_lock lock();
ブースト1.41で完全に機能しました
しかし、プロセス間ロックミューテックスは、boost 1.34 ライブラリではサポートされていません。これは、私の場合に利用できるものです。
コードのストアド プロシージャ セクションを同期して、2 つの呼び出しが同時に行われたときに、一方が実行される前に一方がブロックされるようにする方法はありますか?
(以下を追加)編集されたコード:ストアドプロシージャの同期ブロックで何を実行しようとしているのかを理解するため。
最後に割り当てられた ID を取得し、それを 1 つ増やして、それが別の「名前」レコードに使用されていないかどうかを確認します。有効な ID が見つかったら、最後に割り当てられた ID レコード テーブルを更新し、それを指定された「名前」に関連付けます。
DELIMITER $$
CREATE PROCEDURE SP_GEN_ID(IN NAME VARCHAR(20))
BEGIN
DECLARE maxLen int default 0;
START TRANSACTION;
#the section of code that needs to be synchronized
SELECT lastid into lastgenerated FROM DB_last_id WHERE key = 'NAME_ID';
findid_loop:
LOOP
set lastid = lastid + 1;
#this is to check whether it was assigned with someother name before.
IF not EXISTS (SELECT 1 FROM user_name_id WHERE name_id = lastgenerated) then
set nameid = lastgenerated;
set found = true;
LEAVE findid_loop;
END IF;
#for loop limit check
IF (counter < loopLimit) then
set counter = counter + 1;
ITERATE findid_loop;
ELSE
#reached the limit and not found.
LEAVE findid_loop;
END IF;
END LOOP findid_loop;
#if a valid id, update last id and assign to name.
IF (found) THEN
#update the id.
update DB_last_id set lastid = nameid where key = 'NAME_ID';
insert into user_name_id values (nameid ,name);
ELSE
#return an empty string for the application to take action on the failure.
set nameid = '';
END IF;
#end transaction here.
COMMIT
END;
$$
DELIMITER ;