2013-10-18 3 views
5

Autocommit이 활성화 된 InnoDB를 기반으로하는 모든 테이블을 가진 Mysql 데이터베이스에서 하위 쿼리 및/또는 조인이 포함 된 쿼리는 원 자성이됩니까?MySQL의 조인 삽입/업데이트가 원자 적 연산입니까?

예 :

  • INSERT INTO users SELECT (x,y,z) FROM users, comments WHERE users.id = comments.user_id; (결합)

  • UPDATE users, comments SET users.x = x1 WHERE users.age > 30; (결합)

  • UPDATE users, comments SET users.x = x1, comments.y = y1 WHERE users.age > 30; (결합)

  • UPDATE users, comments SET users.x = x1, comments.y = y1 WHERE users.id IN (SELECT id FROM users WHERE age > 30); (부질)

  • ,617,

답변

5

에서이

START TRANSACTION; 
    SELECT @A:=SUM(salary) FROM table1 WHERE type=1; 
    UPDATE table2 SET [email protected] WHERE type=1; 
COMMIT; 

예처럼 START TRANSACTION에서 그들을 포장하지 않는 한 http://dev.mysql.com/doc/refman/5.0/en/commit.html

+0

그러나 원자적인 것은 암시 적으로 다른 쿼리가 쿼리 실행을 방해하지 않는다는 것을 의미하지 않습니다. "INSERT INTO users SELECT (x, y, z) FROM users, comments WHERE users.id = comments.user_id AND condition"과 같은 쿼리에서 WHERE 조건이 충족되면 업데이트가 올바르게 실행됩니다 후. 그게 옳지 않아? –

+0

@DamianoBarbati 내 대답이 업데이트되었습니다. – fancyPants

+0

가 동의합니다. 내 가정은 행이 다른 테이블에서 복사되고 그 행에있는 데이터가 변경된 질문의 'sql 문'을 기반으로했습니다. –

3

SQL 문은 자동 확약을 사용하여 자동으로 실행되지 않습니다. 자동 커밋을 해제하려면 트랜잭션을 시작해야합니다. 당신은 내가 "그 자체로 그 쿼리 원자 작업의 각입니까?"와 같은 질문을 이해 Mysql manual

4

번호를 참조하십시오. 그렇다면 대답은 "예"입니다. 다른 두 답은 맞습니다. 여러분의 모든 진술이 함께 원자 적이라고 말하는 것은 아닙니다.

데이타베이스에서의 절대성 은 전체 또는 아무 것도 의미하지 않습니다.. 은 데이터의 정확성이 인 것은 아닙니다. 성명서가 성공했는지 여부. 조인이나 서브 쿼리와 아무 관련이 없습니다. 데이터베이스가 메모리 또는 디스크의 임시 테이블을 사용해야하는지 여부와 상관없이 하나의 명령문이 하나의 명령문입니다.

트랜잭션은 데이터베이스에 하나의 명령문으로 여러 명령문을 처리하도록 지시합니다. 명령문 중 하나가 실패하면 모든 명령문이 롤백됩니다.

중요한 관련 주제는 isolation level입니다. 당신은 그것들에 대해 읽을 수 있습니다.

EDIT (주석에 응답하기 위해) : 맞아

. 유효한 진술이고 정전이 발생하지 않거나 쿼리가 실패 할 수있는 다른 이유가있는 한 그 작업이 완료됩니다. Atomicity는 그 자체로 진술이 이루어지고 있는지를 보장합니다. 완전성을 보장하며 데이터가 손상되지 않습니다 (쓰기 작업이 완료되지 않았거나 원인이 없음). 데이터의 정확성을 보장하는 것은 아닙니다.INSERT INTO foo SELECT MAX(id) + 1 FROM bar;과 같은 쿼리가 주어지면 올바른 격리 수준을 설정하여 팬텀 (phantom) 읽기 또는 아무것도 얻지 못하도록해야합니다.

+0

그는 한 문장 내에서 원 자성에 대해 이야기합니다. – Pacerier

0

나는 그것이 thik하지 않으며, 나는 왜 당신을 설명 할 것이다. MySQL에 정말 이상한 문제가있었습니다.

"table1"이라는 테이블이 단일 레코드로 있다고 가정 해보십시오. 열 f1의 값은 "A"입니다.열 f2의 값은 "B"입니다.

Update table1 set f1 = CONCAT(f1,f2), f2 = 'C'; 

f1의 최종 값은 예상대로 'AB'입니다.

는하지만 순서를 변경하는 경우 : F1의

Update table1 set f2 = 'C', f1 = CONCAT(f1,f2); 

마지막 값은 'AC'입니다. 즉, f2가 먼저 변경되고 f1이 변경됩니다.

내 결론은 업데이트 작업이 분명히 비 원자력이라는 것입니다. f2가 먼저 변경됩니다. f1은 원래 값이 아닌 f2의 업데이트 된 값을 사용한 후에 변경됩니다.

관련 문제