php mysql 트랜잭션 lock level, 사용방법 3가지

예시(사용법).

 

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 lockWRITE 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에서 자동커밋기능을 사용할수 있는가?

 

 

댓글

Designed by JB FACTORY