2016-07-19 2 views
0

나는 이것으로 붙어있다. 그것은 간단하게하기 위해, 내가이 테이블mysql에서 동시성을 관리하는 방법은 무엇입니까?

CREATE TABLE IF NOT EXISTS `tbl_bags_oranges` (
    `idbag` int(11) NOT NULL AUTO_INCREMENT, 
    `n_oranges` int(11) NOT NULL, 
    PRIMARY KEY (`idbag`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci AUTO_INCREMENT=1 ; 

그리고 사용자가 오렌지를 잡고있는 상황을 나타내는 PHP 스크립트를 개발하고 있어요 있다고 가정 해 봅시다. 이것은 내가 뭘하는지입니다 :

  1. 내가 주어진 idgab에 오렌지가 있는지 확인하기 위해 SELECT를 사용 그렇다면 (n_oranges는> 0)
  2. , 나는 n_oranges에 1을 뺀 테이블을 UPDATE

하지만 가방에 한 오렌지있을 때 다음과 같은 일이 일어날 수 있습니다

  1. 사용자 A가 오렌지를 잡고 싶은이. 'ELECT '에 오렌지가 하나 있다고되어 있습니다.
  2. 사용자 B가 주황색을 차지하려고합니다. 'ELECT '에 오렌지가 하나 있다고되어 있습니다.
  3. 사용자 A가 오렌지를 움켜 잡습니다. I UPDATE 표와 지금 n_oranges = 0입니다.
  4. 사용자 B는 SELECT에 오렌지가 하나 있다고 말했기 때문에 오렌지를 움켜 잡을 수 있습니다.

어떻게이 질문을 해결할 수 있습니까? 업무? LOCK TABLES? 이 상황을 확인할 수 없기 때문에 내가 잘하고 잘못했는지 알 수있는 방법이 없습니다.

UPDATE `tbl_bags_oranges` 
SET n_oranges=n_oranges-1 
WHERE n_oranges>=1; 

당신은 당신의 상황에 따라 코드를 수정할 수 있습니다 :이 같은 테이블 무언가를 업데이트 할 때

+1

[의도 잠금] (http://stackoverflow.com/a/38079598)을 수행하십시오. 너는 다소 비슷할 것이지만 감소 할 것이다. 두 번째로, 안전합니다. – Drew

+0

한 번에 업데이트하기 전에 n_oranges에 다시 체크를 해 보았습니까? –

답변

0

locking reads을 사용할 수 있습니다. 상세 :

  • 만들 확실히 autocommit 사용할 수 없습니다
  • START TRANSACTION
  • SELECT ... FROM tbl_bags_oranges WHERE ... FOR UPDATE
  • 이 새로운 값 UPDATE tbl_bags_oranges SET ...
  • COMMIT
  • 을 저장 코드에서해야 할 다른 무엇이든

이 경우 시나리오에서 첫 번째 트랜잭션이 커밋되고 경쟁 조건이 발생하지 않을 때까지 두 번째 쿼리가 차단됩니다.

+0

정확히 내가 찾던 것이 었습니다. 고마워요! – DandyCC

0

당신은 검사를 할 수 있습니다.

+0

죄송합니다. 내 잘못입니다. 질문을 명확하게하기 위해 가능한 한 간단하게하고 싶었고 나의 예가 너무 단순하다는 것을 깨닫지 못했습니다. 사실 나는 3 개의 다른 테이블에서 값을 확인한 다음 그 중 하나를 업데이트해야합니다. – DandyCC

관련 문제