2012-02-05 2 views
0

이전에 거래를 사용할 때 문제가 발생했습니다. 누군가가 알아낼 수 있기를 바랍니다. 나는 어떤 도움을 주셔서 감사하겠습니다. 고맙습니다.서로 다른 트랜잭션의 데이터를 업데이트하기 위해 인덱싱 된 열과 인덱싱되지 않은 열을 사용하는 것의 차이점은 무엇입니까?

MySQL의 테이블 구조 :

create table test (
    id int not null, 
    someid int, 
    name varchar(50), 
    update_date datetime 
); 
primary key : id (auto-inc) 
index1 : id (unique) 
index2 : id, update_date (non-unique) 

자바 방법

여기
// consider this method is Transaction 1 
method1() { 
    A. set session transaction isolation level read commited; 
    B. select update_date from test where someid = 1; 
    C. insert into test values (some new data..); 
    D. select update_date from test where someid = 1; 
} 

// consider this method is Transaction 2 
methodb() { 
    E. (start with default transaction isolation level - repeatable read) 
    F. update test set udpate_date = now() where someid = 1; 
} 

내가 짓이다

  1. 방법 항목()를 실행하고 (Eclipse에서 설정된 브레이크 포인트) 침입 D
  2. execute method2() concurrent

"someid"는 색인에 없지만 "id"와 똑같은 데이터를 저장한다는 점에 유의하십시오.

그렇다면 트랜잭션 1을 커밋하지 않는 한 기다리는 동안 아무 것도 얻지 못하거나 결국 트랜잭션 시간 초과로 끝날 것입니다. 하지만 만약 id = 1이 F의 where 절을 변경했다면 아무런 대기없이 잘 작동 할 것입니다. 내가 테이블이나 행을 잠그지 않았으므로 혼란스러워졌습니다. 내가 그랬다면 안된다. 그렇지?

아무도 왜이 말을 들려 줄 수 있습니까? 고맙습니다!

답변

1

조건 someId = 1은 인덱스가 없기 때문에 데이터베이스 시스템이 전체 테이블을 스캔해야합니다. insert 문은 someid = 1 인 행을 삽입 할 수 있으므로 두 번째 트랜잭션의 결과에 영향을 줄 수 있습니다.

id = 1 인 경우 dbs는 하나의 행만이 statment F의 영향을 받는지 확인할 수 있습니다. insert statment는이 행을 변경하지 않습니다.

격리 수준이 실행에 영향을 미치는지 궁금합니다.

+0

답장을 보내 주셔서 감사합니다. 업데이트가 어떻게 효과가 있었는지에 대해 이해합니다. 적어도 그렇게 생각합니다. 글쎄, 나는 거래에 익숙하지 않다. 그러나 격리 수준이 적어도 갱신 통계에 영향을 준다는 것을 믿기는 거의 어렵다 :-) – redfoxlee

+0

btw : 격리 수준이 잠금 모드에 영향을주는 것처럼 보입니다. 하지만이 경우에는 READ COMMITED와 REPEATABLE READ의 차이점을 알 수 없습니다. – redfoxlee

1

MySQL 동시성 제어에 대한 전문 지식은 없지만 첫 번째 트랜잭션이 커밋 될 때까지 두 번째 트랜잭션이 삽입 된 행이 커밋 될지 여부를 알 수 없습니다 , 그래서 실속해야합니다.

두 번째 트랜잭션이 계속 할 수있는 첫 번째 트랜잭션이 완료 후에 만 ​​다음 중 하나를

  • 갱신 (첫 번째 트랜잭션 커밋 경우) 행 첫 번째 트랜잭션이 롤백 경우
  • 여부는 (행을 갱신, 그래서 행은 실제로 삽입되지 않았습니다).

질문 : 왜 색인화 된 id도 발생하지 않았습니까? someid처럼 두 거래에 동일한 값을 사용 했습니까? 두 트랜잭션 모두에 대해 WHERE 절을 변경 했습니까?

+0

먼저 답장 해 주셔서 감사합니다. 내 목표는 "테스트"의 일부 데이터를 템플릿으로 복사 한 다음 다시 동일한 테이블에 삽입하는 것입니다. 그래서 내가 올바른 복사본을 가지고 있는지 확인해야합니다. 그래서 위의 방법을 확실히 사용했습니다. 그리고 네, 두 거래에 동일한 가치를 사용했는지 확신합니다. 글쎄요, 모르겠지만, 지금은 tkr의 대답이 여기에 의미가있는 것처럼 보입니다 :-). 다른 아이디어? – redfoxlee

+0

@redfoxlee 두 번째 트랜잭션이 첫 번째 트랜잭션이 커밋 될 때 _exactly_의 블록을 해제한다는 사실은 잠금과 관련된 일종의 강력한 표시입니다. 어떤 스토리지 엔진을 사용하고 있습니까? MyISAM (http://dev.mysql.com/doc/refman/5.6/en/internal-locking.html) 엔진에 대한 흥미로운 견적을 발견했습니다 : _ "구멍이 있으면 병행 삽입이 비활성화되어 있지만 활성화되어 있습니다 모든 구멍이 새 데이터로 채워지면 자동으로 다시 시작됩니다. " 이 구멍을 치는 게 불행했을까요? 기술 한 행동이 일관되게 발생합니까? 여러 번 테스트 했습니까? –

+0

글쎄, 나는 시작한 이래로 얼마간 불행 해왔다. 그러나 InnoDB 엔진을 사용하고 있기 때문에 확실한 것은이 행운이다 :-). 그리고 네,이 테스트를 여러 번했고 매번 발생합니다 :-( – redfoxlee