2011-11-16 4 views
0

빠른 질문/설명이 필요합니다. 나는 아마도 레코드에 대한 동시 업데이트가 가능한 DB 테이블을 가지고있다. 나는 응용 프로그램에 젠드 프레임 워크를 사용하고 있는데,이 문제를 피하기 위해 두 가지 방향에 대해 읽었습니다. 먼저 테이블 잠금 (LOCK TABLES WRITE) 또는 그런 식으로 돌아가서 정확히 어떻게 할 것인지 다시 읽습니다. 그게 최선의 해결책입니다. 두 번째 트랜잭션 : $ db-> beginTransaction(); ... $ db-> commit();MySQL 트랜잭션 대 잠금

이제 'InnoDB와 같은 트랜잭션 스토리지 엔진을 사용한다고 가정하면 트랜잭션이 일반적인 솔루션처럼 보입니다. 그러나 그 다음과 같은 시나리오를 피하기 않습니다 -> 데이터 제출 -> 새 값을 계산 - -> 읽기 행 -> 트랜잭션을 시작> 업데이트 행 -

사용자 A가 웹 페이지에> 저장 ->

사용자를 저지 B가 동시에 같은 웹 페이지에 있고 동시에 데이터를 제출하면 이제는 거의 동시이라고 말할 수 있습니다 (사용자 B가 트랜잭션 시작과 사용자 A 트랜잭션에 커밋하는 시점에서 업데이트 기능을 호출 함). 사용자 B는 레코드 업데이트에 대한 정확한 계산을 수행하기 전에 사용자 A 트랜잭션의 커밋 된 데이터

IE : 데이터베이스 행에

열기 값 : 5 사용자 A는 5의 값이 ( 거래를 시작 제출 -> 읽기 값을 (5) -> 제출 된 값을 추가 (5 + 5 = 10) -> 업데이트 된 값을 쓰기 -> 저장 -> 업데이트하면

사용자 B가 (5 읽었 사용자 B의 트랜잭션의 값이 10이 있는지 확인해야합니다 (7)의 값을 제출하고되지 않음) 커밋 읽기 전에 을 수행하지 않았습니다.

나는 이것이 오래 지속 된 설명이라는 것을 알고있다. 나는 사과한다. 질문을 단순화하기위한 정확한 용어를 정확히 모르겠다.

감사합니다.

+1

'UPDATE table SET value = value + 5'와 (과) 같이 할 수 있습니까? 그런 다음 거래가 필요하지 않습니다. –

+0

그게 효과가있다, 내 인생을 쉽게 만들 것입니다. 내가 만날지도 모르는 하나의 문제. 업데이트를 수행 한 다음 값을 읽기 전에 두 번째 세션에서 업데이트를 수행하고 올바른 값을 원래 사용자에게 다시 보내야합니다. 그래서 그것은 현재의 'value'를 검색하기위한 업데이트와 select입니다. 읽기가 발생하기 전에 두 번째 업데이트가 싫어지면 반환 된 결과가 유효하지 않을 것입니다 (또는 잘못된 것입니다). 내 관심사에 대한 이유는 업데이트되고 사용자에게 반환 될 때 데이터가 100 % 보장되어야한다는 것입니다. –

+0

나는 100 % 정확하다고 생각하지 않는다. 올바른 값을 읽었을지라도 사용자에게 보내고 잠금을 해제하는 순간에 유효 기간이 지났을 수 있습니다. 실시간 데이터베이스 업데이트를받는 이벤트 기반 시스템을 사용하지 않는 한 현재 값을 유지할 수는 없습니다. (그럼에도 불구하고 눈에 띄는 지연이있을 수 있습니다.) –

답변

0

거래가 잠금을 보장하지 않습니다. 트랜잭션의 전체 블록은 db에 대한 원자 적 업데이트로 처리됩니다 (이 블록의 모든 이전 변경 사항 사이에 실패가 롤백 인 경우). 따라서 병렬로 실행되는 두 개의 트랜잭션이 동일한 행을 업데이트 할 수 있습니다.

둘 모두를 사용해야합니다.

Transaction do 
row.lock 
update row 
end 

참조하십시오. 행 수준 잠금을 사용하면 u.

+0

나는이 답변을 순수하게 원래의 답변에 기반하여 받아 들일 것입니다. (빠른 버전)에 대한 질문은 "거래가 경쟁 조건을 보호합니다"라고 대답하고 대답은 '아니오'입니다. @MichaelMior의 의견은 저의 의견을 다른 시각에서 바라 보았고 좀 더 실행 가능한 해결책을 제시하는 데 도움이되었다고 생각합니다. 둘 다/평화 감사합니다! –