>  기사  >  백엔드 개발  >  PHP의 원자적 연산 및 파일 잠금 무리 소개(코드 예)

PHP의 원자적 연산 및 파일 잠금 무리 소개(코드 예)

不言
不言앞으로
2019-01-28 10:00:482652검색

이 기사는 PHP의 원자 연산 및 파일 잠금 무리에 대한 소개를 제공합니다(코드 예제). 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

PHP 원자 연산, 파일 잠금 무리, 데이터베이스 트랜잭션

PHP는 POSIX 표준에서 지원하는 Unix 잠금을 상속하지 않습니다. 이는 Linux 시스템 호출 무리만 캡슐화합니다(논리적으로는 세마포어를 잠금으로 사용할 수도 있음). 약간 덜 효율적이긴 하지만 잠금 메커니즘을 사용할 수도 있습니다.
php 스크립트는 fastcgi 컨테이너에서 실행되며 fastcgi는 다중 프로세스이므로 PHP 프로그램이 중요한 리소스에 액세스하면 필연적으로 잘못된 프로그램 결과가 발생합니다.
fastcgi 컨테이너 문제도 고려해야 할 것으로 추정됩니다

문제 설명: 해커가 사용하는 도구가 백엔드를 공격합니다.
해커가 주문을 동시에 취소하면 환불이 여러 번 발생합니다.
한 번만 요청하면 환불됩니다. 간격이 100밀리초이면 문제가 없습니다

PHP 처리 과정은 환불 플래그를 읽고 환불이 없음을 확인한 후 환불된 플래그를 설정하는 것입니다
문제는 여러 요청이 있다는 것입니다. 동시에 도착하고 환불 플래그가 읽혀집니다. 어느 것도 환불되지 않았으므로 여러 요청이 동시에 여러 번 요청되었으며 C++에서는 동시에 포트를 수신합니다. , HTTP 패킷을 직접 수신한 다음 HTTP 형식으로 패킷을 반환합니다. PHP 프로그램에서 컬을 사용하여 내 C 프로그램에 액세스합니다.

원격 호출과 동일하며 배포를 위해 다른 서버에 배포할 수 있습니다
특히 PHP 코드가 리소스를 읽고 쓸 수 있는 경우에는 PHP 코드의 병렬 기능을 고려하지 않습니다. 그러나 이것이 PHP의 모든 작업이 원자적이고 트랜잭션이 가능하며 병렬화 가능하다는 의미는 아닙니다. PHP 스크립트는 fastcgi 컨테이너에서 실행되고 fastcgi는 다중 프로세스이므로 PHP 프로그램이 중요한 리소스에 액세스하면 필연적으로 잘못된 프로그램 결과가 발생합니다. 문제에 대한 해결책은 잠금 장치를 사용하는 것입니다. PHP는 POSIX 표준에서 지원하는 Unix 잠금(예: 레코드 잠금 fcntl, 스레드 잠금 등)을 상속하지 않지만 Linux 시스템 호출 무리(세마포어를 잠금으로 사용할 수도 있음)만 캡슐화하며 무리 형식은 무리( $fp,$type), 여기서 $fp는 파일 핸들이고 $type은 다음과 같습니다.
/* 파일이 읽기 및 쓰기 가능한 방식으로 열리면 일반적으로 파일에 잠금 메커니즘을 추가해야 합니다 */ 1. LOCK_SH 공유 잠금:

일반적으로 프로세스 지정 잠금입니다. 파일이 읽기 작업을 요청할 때 공유 잠금을 추가해야 합니다. 공유 잠금은 모든 프로세스 간 읽기 작업을 지원할 수 있습니다. 공유 잠금이 해제될 때까지 프로세스가 차단되고 SLEEP 상태로 들어갑니다.

2. 일반적으로 쓰기에 추가됩니다. 파일에 대한 프로세스 작업 독점 잠금 파일에 잠금이 추가되면 잠금이 해제될 때까지 파일에 액세스할 때 다른 모든 프로세스가 차단됩니다.


3. LOCK_UN 잠금 해제:

잠긴 파일 핸들 잠금 해제


이 잠금 방법은 확실히 잠긴 프로그램 블록의 원자성을 보장할 수 있지만 프로그램의 효율성도 희생시킵니다. 따라서 실제 프로그램은 작은 프로그램 논리로 포함되어야 합니다. 프로그램의 잠금 및 잠금 해제 코드(특히 배타적 잠금) 사이에 가능한 한 빨리 프로그램이 잠금 해제되도록 합니다.

마지막으로 잠금 메커니즘을 추가한 후 프로그램을 첨부합니다.

<?php 
$usrinfo = isset($_GET["usrinfo"])?$_GET["usrinfo"]:exit(1); 
$stinfo = isset($_GET["stinfo"])?$_GET["stinfo"]:exit(1); 
echo $stinfo; 
$pid = posix_getpid(); 
$fp = fopen(“usrinfo.txt”,”a+”); 
$num = rand(0,100000); 
flock($fp,LOCK_EX); 
fwrite($fp,”user:”.$usrinfo.” stinfo:”.$stinfo.”–”.$pid.”–”.$num.”\n”); 
fwrite($fp,”talking 1 — pid:$pid and num:$num\n”); 
flock($fp,LOCK_UN); 
fclose($fp);

정상적인 상황에서 이 프로그램을 실행하면 올바른 결과가 생성됩니다.


일괄 작업 중에 원자성을 보장하기 위해 어떤 방법을 사용할 수 있나요?

예: 여러 기사를 삭제했지만 그 중 하나가 삭제되었습니다. 여기에서 오류가 발생하면 전체 작업을 롤백하고 오류 메시지를 찾는 방법은 무엇입니까?

데이터베이스 트랜잭션은 원자성을 보장하지만 오류 정보를 찾을 수 없습니다. 하지만 트랜잭션을 사용할 수 없는 시나리오가 발생하면 어떻게 해야 할까요?

데이터베이스 트랜잭션을 사용하는 것이 가장 합리적입니다. 작업이 실패하면 오류가 발생합니다.

모든 작업이 기록되고 성공 또는 실패가 기록되도록 논리를 적용합니다. 중간에 문제가 발생하면 성공을 되돌릴 수 있습니다. 일반적으로 우리의 삭제는 가짜 삭제이므로 매우 쉽습니다. 삭제한 경우 녹음 시 완전한 정보를 기록해야 합니다.

PHP는 파일 잠금을 사용하여 프로세스 잠금을 시뮬레이션하여 원자성 작업을 구현합니다.

PHP를 사용하여 원자성 작업을 구현하지만 PHP 자체는 프로세스 잠금 메커니즘을 제공하지 않습니다. PHP 파일 잠금 메커니즘을 사용하여 파일 잠금을 통해 프로세스 잠금을 시뮬레이션하여 원자성 작업을 수행합니다. .

원자적 연산을 위한 코드 이전에 배타적 잠금을 사용하여 파일을 여는 코드는 다음과 같습니다.

$fp = fopen( LOCK_FILE_PATH, "r" );
if (!$fp) {
 echo "Failed to open the lock file!"; 
 exit(1);//异常处理
 }
flock ( $fp, LOCK_EX );

원자적 연산을 위한 코드 이후에는 파일을 잠금 해제하고 파일을 닫습니다.

flock ( $fp, LOCK_UN );
fclose ( $fp );

전체 의사 코드는 다음과 같습니다.

define("LOCK_FILE_PATH", "/tmp/lock");
if( !file_exists(LOCK_FILE_PATH) ){ 
$fp = fopen( LOCK_FILE_PATH, "w" );
fclose ( $fp );
}
$fp = fopen( LOCK_FILE_PATH, "r" );
if (!$fp) {
echo "Failed to open the lock file!";
exit(1);//异常处理
}
flock ( $fp, LOCK_EX );
//此处添加原子操作代码
flock ( $fp, LOCK_UN );
fclose ( $fp );

위는 PHP 원자 연산을 구현하고 충돌을 피할 수 있습니다.

php 원자 연산 및 mysql 원자 연산

원자적 작업에 일반적으로 사용되는 방법은 데이터 롤백을 구현하는 것입니다. PHP를 사용하여 데이터베이스 롤백 작업을 구현하는 것은 매우 간단합니다.
1, 데이터베이스 연결 설정
2, mysql_query('BEGIN'), $SQL = " ...";
mysql_query($SQL); 해당 데이터베이스 작업 수행
4, 롤백 조건 결정:
if(mysql_errno)
{
print mysql_error(); 오류가 있는 경우 롤백
exit(); 발생
}
5. 위의 3단계와 4단계를 반복할 수 있습니다. 초기 프로세스(데이터베이스 업데이트에만 국한되지 않고 중간에 다른 작업을 추가할 수 있지만 트랜잭션도 너무 오래 걸리지 않도록 주의하세요) 사용하는 모든 테이블을 잠그기 때문에 다른 프로그램의 사용에 영향을 미칩니다.)
롤백되는지 확인하기 위해 여러 개의 올바른 SQL 업데이트 문 후에 의도적으로 잘못된 것을 작성할 수도 있습니다.
6, 롤백 작업 종료
mysql_query('COMMIT'); 여기에 도달할 수 있다는 것은 위의 데이터베이스 작업이 모두 정확하고 공식적으로 실행을 위해 제출되었음을 의미합니다.

이것은 원자적 작업을 구현하기 위해 PHP를 사용하는 전체 프로세스입니다. 데이터 롤백 작업의 지원 테이블 구조를 설정하는 데 특별한 주의가 필요합니다.

또한 커밋 외에 롤백 작업을 종료하는 다른 방법이 있습니다.


위 내용은 PHP의 원자적 연산 및 파일 잠금 무리 소개(코드 예)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 cnblogs.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제