php mysql 트랜잭션 lock level, 사용방법 3가지
- 프로그래밍/sql,db,mysql
- 2019. 5. 17.
예시(사용법).
global $DBINFO;
//생략@mysqli_query("SET AUTOCOMMIT=0", $conn);
@mysqli_query($DBINFO, "BEGIN");
$rs = @mysqli_query($DBINFO, "select * from _MEMBER where id='asdeqwe@asdt.com' FOR UPDATE");
@$row = assoc($rs);
.......do..something
//완료처리
@mysqli_query($DBINFO, "COMMIT");
//상황(조건, 처리결과 if)에 따라 복원처리
@mysqli_query("ROLLBACK", $conn);
---------------------------------------------------------------------------------------------------------
기본 개요.
MySQL 5.1까지는 MyISAM이 기본 엔진으로 설정되어 있음
MyISAM은 당시의 InnoDB에 비하면 처리 속도가 매우 빨랐으나 트랜잭션을 지원하지 않음
요즘에는 innodb의 성능도 엄청 좋으며, row-lovel locking으로 myisam보다 더 좋은 성능이라 생각됨
트랜잭션이란?
여러 단계의 처리를 하나의 처리처럼 다루는 기능을 트랜잭션(transection)
데이터베이스에 반영하는 것을 커밋(commit)이라 하고
반영하지 않고 원래 상태로 되돌리는 것을 롤백(roll-back)
1.트랜잭션 시작
START TRANSACTION; or BEGIN
2.커밋 또는 롤백
ROLLBACK; COMMIT;
3.자동커밋기능
SET AUTOCOMMIT=0; //1
** begin 하면 autocommit=0
connect 한 세션에서만 영향이 있는 값이라 autocommit 자체를 생략하고
begin commit 만 하면 됨
---------------------------------------------------------------------------------------------------------
about LOCK 락에 대하여
1.MyISAM - Table-Level Locking
테이블 잠금은READ lock과WRITE lock이 있습니다.
- READ lock 을 걸면 UNLOCK 하기 전까지 다른 세션에서 조회가능 / 입력, 수정, 삭제 불가, 대기
- WRITE lock 을 걸면 UNLOCK 하기 전까지 다른 세션에서는 조회불가능, 대기
- 테이블 잠금이 유지되는 동안 잠긴 테이블에 대해서만 액세스 / 여러 테이블을 읽을 경우 모든 테이블의 잠금을 하나의 LOCK TABLES 문에 모두 나열
ex)
LOCK TABLES tb_stock, tb_order READ; //or WRITE
UNLOCK TABLES;
2.InnoDB - Row-Level Locking
행 수준의 잠금
- 트랜잭션을 시작하고 FOR UPDATE 문을 사용하면 조회 된 행에 대해서는 commit 또는 rollback 으로 트랜잭션이 종료될 때까지 조회, 입력, 수정, 삭제가 모두 불가
- 공유모드(LOCK IN SHARE MODE)로 잠그면 다른 세션에서 조회가능/수정, 삭제불가
- Row-Level Lock 을 사용할 때는 데드락(Dead-Lock) 이 발생하지 않도록 주의
ex) SELECT * FROM _MEMBER WHERE id=1 FOR UPDATE;
ex) SELECT * FROM _MEMBER WHERE id=1 LOCK IN SHARE MODE;
3.Optimistic Lock
이노db, 마이아이삼db 둘다 사용가능
- 낙곽적인 잠금은 실제로 Lock 을 얻어서 잠그는 것이 아님.
- 단일 쿼리는 원자적이므로 하나의 쿼리가 실행되는 동안에는 끼어들 수 없다는 것을 이용하여 동시성을 제어
ex)
1.일반 적인 방식
1)조회
SELECT uuid, flag FROM _MEMBER WHERE id = 1;
2)업데이트
UPDATE _MEMBER SET uuid=uuid-1, flag=flag+1 WHERE flag= '조회시값' AND id = 1;
3)affected row 가 0이면 조회 당시의 flag가 변경되었을 것입니다. 이것은 내가 조회하고 업데이트하기 전에 누가 먼저 업데이트 했다는 것을 뜻하므로 실패로 처리합니다.
UPDATE tb_stock SET quantity=quantity-1 WHERE quantity-1 >= 0 AND id = 1;
출처:https://offbyone.tistory.com/225
---------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------
질문
1. myisam에서 자동커밋기능을 사용할수 있는가?
'프로그래밍 > sql,db,mysql' 카테고리의 다른 글
mysql 8.0 비밀번호 초기화 --skip-grant-tables (0) | 2021.09.24 |
---|---|
mysql 쿼리문 통계 (주간/일간/월간/기간별) (0) | 2020.02.13 |
mysql 5.1 / 5.7 default-character-set 설정하는방법 my.cnf (0) | 2020.02.06 |
mysql 슬로우 쿼리 로그 설정 및 테스트 (0) | 2019.08.28 |
mysql 임시비밀번호 에러 Your password has expired. To log in you must change it using a client that supports expired passwords. (0) | 2019.05.24 |