PHP ファイルロックで排他処理

ファイルロック
2014/01/31

ファイルロックで排他処理

概要

PHPのflock関数を使って排他処理を行う方法を紹介しています。
Webアプリでは、複数のプロセスが同時に実行されますが、処理によっては競合してしまいエラーとなるものもあります。

そういった時に、flock関数のファイルロックする機能を利用して、同時に処理が行われないよう実装します。

サンプルコード

flock関数の説明

基本的には次のような流れで処理を行います。

  • ロックするファイルをfopen関数で開く
  • flock関数でモードを指定してロック
  • fclose関数で解放

ロックモードは次のものが指定できます。

定数 説明
LOCK_SH 共有ロック。ロックされていた場合は解除されるまで待つ。
LOCK_EX 排他的ロック。ロックされていた場合は解除されるまで待つ。
LOCK_UN ロックを解除。
LOCK_SH | LOCK_NB 共有ロック。ロックされていた場合はfalseを返す。(Windowsではサポートされない。)
LOCK_EX | LOCK_NB 排他的ロック。ロックされていた場合はfalseを返す。(Windowsではサポートされない。)

LOCK_NBはWindowsではサポートされていませんが、試したところ使えました。
なぜでしょう。。。

普通にロック

まずは普通にファイルロックを使用して、複数アクセス時にも処理が被らないようにします。


$lock=$this->start_lock();
~処理~
fclose($lock);

function start_lock()
{
	$lock = 'hoge.lock';

	if (!$fp=fopen($lock, "a")) die("can't lock");
	flock($fp, LOCK_EX);
	return $fp;
}

グループ化してみる

グループ化してロックしたい場合は、ロックモードを使い分けて行います。


//一つ目の処理
$lock=start_lock4();
$lock_wait=start_lock();
fclose($lock_wait);
~処理~
fclose($lock);

//二つ目の処理
$lock=start_lock4();
$lock_wait=start_lock();
fclose($lock_wait);
~処理2~
fclose($lock);

//三つ目の処理
$lock=start_lock2();
$lock_wait=start_lock3();
fclose($lock_wait);
~処理3~
fclose($lock);

function start_lock()
{
	$lock = 'hoge.lock';

	if (!$fp=fopen($lock, "a")) die("can't lock");
	flock($fp, LOCK_EX);
	return $fp;
}
function start_lock2()
{
	$lock = 'hoge.lock';

	if (!$fp=fopen($lock, "a")) die("can't lock");
	flock($fp, LOCK_SH | LOCK_NB);
	return $fp;
}

function start_lock3()
{
	$lock = 'hoge2.lock';

	if (!$fp=fopen($lock, "a")) die("can't lock");
	flock($fp, LOCK_EX);
	return $fp;
}

function start_lock4()
{
	$lock = 'hoge2.lock';

	if (!$fp=fopen($lock, "a")) die("can't lock");
	flock($fp, LOCK_SH | LOCK_NB);
	return $fp;
}

一つ目と二つ目の処理をグループ化してみました。
う~ん。。。微妙ですね。。。w

Related

Vagrant+Docker+PHP環境で「session.save_path」指定時に、セッションファイルが空になるエラー

ファイル共有でのフォルダの所有者を設定 結論 PHP5.4.28 からセッションファイルのownerはrootもしくはWebサーバのユーザに限るという制限が...

LINEと連携したテイクアウト事前注文システム徹底比較!

目次 テイクアウト予約・注文受付システムのトレンド LINEと連携したテイクアウト事前注文システムの価格表 L.B.B.Cloud テイクイーツ ...

PHPで動画の撮影日を取得

PHPで動画の撮影日を取得 概要 PHPからffprobeコマンドを実行し、動画の撮影日時を取得します。 コード $posted_at = ...

FullCalendarでGoogleカレンダーのようなUIを実装

jQueryプラグインFullCalendarのサンプル 概要 FullCalendarを使用して、GoogleカレンダーのようなUIを実装する使用例を...

PHP Laravel5.2でmulti-auth(複数テーブルでの認証)を実装

Laravel5.2でマルチ認証 概要 LaravelとはPHPの中で今最も伸びているフレームワークです。 処理速度が遅いなどありますが、かなり使い安く拡...

PHP 正規表現でIPアドレス形式の文字列か判定

正規表現でIPアドレスの入力チェック 概要 フォームで入力されたIPアドレスが正当な文字列か判定するためのバリデーション処理を実装します。 基本的...
トップへ戻る