나는 데이터베이스 무결성에 대해 알게되었고 데이터를 일관된 상태로 유지하기 위해 여러 개의 명령문을 수행해야 할 경우 트랜잭션을 사용해야합니다. Database development mistakes made by application developers은 (지점 16, 선택한 답)어떤 트랜잭션이 데이터 무결성을 약화 시키는가?
Wikipedia는 예를 사용 식료품에
- 직불 $ 100를 지출 계정을
- 계정
확인에 신용 $ (100) 내가 비를 입금하려고하면 - 존재하는 계정 ID 및 제약 조건을 올바르게 사용하고 있습니다. 예외가 발생하고 catch하고 롤백 할 수 있습니다. 정전이 발생하면이 두 가지 변경 사항이 원자 적으로 보장됩니다. 내가 제대로 이해한다면
그러나, 그 자체로 거래는 모든 경우에 나에게 도움이되지 않습니다 :
- MySQL은 (예를 PHP와 MySQL과) : 시작 거래
- MySQL의 : 데이터를 선택합니다 테이블에서
- PHP : 선택된 데이터와 계산 상태
- PHP : 상태가 유효하다면, 데이터를 삽입
- PHP : (
쿼리를 함께 실행 될 수 있기 때문에이 작동하지 않습니다 원자 실패없이이 있다고 결정 그것의 PHP를 커밋 트랜잭션 그렇지 않으면, 데이터
둘째, 테스트 한 결과 트랜잭션은 동 기적으로 커밋되지만 비동기 적으로 시작할 수 있습니다. 트랜잭션을 시작하고 10 초 지연을 추가하면 느린 스크립트를 시작하여 그 시간에 다른 트랜잭션을 시작하고 커밋 할 수 있습니다. 동시 트랜잭션을 보여줍니다. 다른 인스턴스의 수정 사항을보기 전에 두 인스턴스가 동일한 데이터를 선택할 수 있습니다. 변경 사항 만이 원자 적으로 보장됩니다.
그럼 어떻게해야합니까? 나는 테이블을 잠그는 것이 효과적이라고 생각하지만 그 좋은 습관은 무엇입니까? 일부 조건은 SQL로 단일 명령문에 기술 될 수 있지만 더 복잡한 명령문은 할 수 없습니다.
흠, 이것이 단순한 경우에만 유용하다는 것을 이해한다면 (이는 질문하는 것이 아닙니다). 예를 들어,'SELECT ... FOR UPDATE'는 여러 번 중요 합니다만 한 행으로 작업 할 때만 작동합니다. 'select ... where value = old value'와 동일합니다. 잘 알고 있지만, 많은 데이터를 선택하고 그 결과를 계산하여 앞으로 나아갈 지 여부를 결정해야한다면 어떻게해야할까요? 이러한 경우 테이블 잠금이 허용됩니까 (매우 조심해야하는 것 같습니다)? – Raekye
@Raekye 두 기법 모두 여러 행에 사용할 수 있지만 선택한 모든 행을 잠그기 때문에 업데이트에 대한 선택 작업이 훨씬 쉬워집니다. –
여러 행 (심지어 테이블)에서 데이터를 선택하면 업데이트되지 않지만 조건을 계산하여 다른 행이 삽입되어야하는지 알 수 있습니다. – Raekye