2012-05-05 4 views
0

PHP를 사용하여 프로젝트에서 내 sql 문을 실행하기 위해 beginTransaction()을 사용하여 성공적으로 시도했습니다. 데이터베이스에 항목을 배열해야하며 각 항목은 저장되기 전에 무언가에 대해 유효성을 검사해야합니다. 데이터베이스의 자동 커밋 동작을 해제하는 좋은 방법 중 하나는 중간에 문제가 발생하면 전체 트랜잭션을 롤백 할 수 있다는 것입니다. 내 프로젝트에서 한 항목이 잘못된 경우 전체 배열을 데이터베이스에 기록해서는 안되며이 때문에이 방법을 선택했습니다.롤백으로 성능이 향상됩니까?

이제 성능면에서 더 좋은 방법인지 궁금합니다. 왜냐하면 배열의 마지막 항목이 유효화 되었더라도 이전 실행을 수동으로 commit()해야하기 때문입니다. 커밋이 SQL 실행을 반복합니까?

내가 지금 생각할 수있는 유일한 장점은 모든 항목을 유효하다고 가정하고 각각을 검증하려는 경우 두 개가 아닌 하나의 루프 만 수행하면된다는 것입니다.

+4

SQL은 데이터베이스 제품이 아닙니다. 이것은 많은 RDBMS에서 사용되는 언어 일뿐입니다. ' 어떤 데이터베이스 시스템을 사용하고 있으며 어떤 버전입니까? – Ben

+0

@Ben, postgresql – Michael

+0

약간 OT : 변경 사항의 유효성을 데이터베이스 상태와 변경 자체를 살펴봄으로써 결정할 수 있다면, 비즈니스 논리가 다음과 같이되도록 BEFORE 트리거에 유효성 검사를하는 것이 가장 좋습니다. 사용 된 응용 프로그램 코드의 클라이언트와 상관없이 적용됩니다. – kgrittn

답변

0

SQL 실행을 반복하지 않습니다.

일반적으로 트랜잭션에서 작업 할 때 INSERT/UPDATE/DELETE 문을 실행할 때마다 데이터베이스는 레코드/데이터 페이지의 복사본을 트랜잭션 로그로 가져 와서 실제 레코드 변경 내용을 실행합니다.

다른 누군가가 트랜잭션 중에 이러한 레코드/데이터 페이지에 액세스하려고하면 트랜잭션 로그의 복사본으로 리디렉션됩니다.

그런 다음 커밋을 실행하면 데이터베이스 자체의 데이터가 이미 업데이트되고 모든 서버는 트랜잭션 로그를 삭제해야합니다.

커밋하지 않고 롤백하는 경우 데이터베이스 서버는 트랜잭션 로그를 역 추적하여 업데이트 한 모든 레코드/데이터 페이지를 원래 상태로 복원하고 각 트랜잭션 로그 항목을 그대로 삭제합니다.

따라서 롤백은 데이터베이스 서버가 트랜잭션 전 상태로 데이터를 복원해야하기 때문에 오버 헤드입니다.

+3

롤백의 구현에 대한이 설명은 PostgreSQL에 적용되지 않습니다. PG를 사용하면 업데이트 전 레코드가 아무 데나 복사되지 않고 그대로 유지됩니다. 트랜잭션 ID가있는 행이 최신인지 여부는 시스템이 어느 시점에서인지합니다. 오버 헤드는 대체로 어느 시점에서 발생합니다. VACUUM은 사용되지 않는 행 버전에서 사용되는 디스크 공간을 회수해야하지만 커밋과 롤백 모두에 해당됩니다. –

+0

나는 고쳐서, 나는 Postgresql 태그를 놓쳤다. –

+0

그래서 Daniel은 PostgreSQL에서 롤백이 인상적이라는 것을 의미한다고 말했다. – Kuberchaun

2

먼저 모든 항목의 유효성을 검사 한 다음 트랜잭션, 데이터베이스 상호 작용을 시작하십시오. 데이터의 유효성을 검사하는 데 도움이되지 않는 거래.

+0

내가 말했듯이, 모든 것을 먼저 검증하면 모든 것이 정상이라고 가정하고 배열을 다시 루프하여 db에 각 항목을 작성해야합니다. – Michael

+0

이것은 일반적으로 좋지 않습니다. 트랜잭션이 시작되기 전에 어떤 것이 사실 이었기 때문에 데이터베이스 외부에 동기화가없는 한 트랜잭션을 적용 할 때 여전히 * 사실임을 증명하지 못합니다. 트랜잭션은 병행 수정시에도 데이터베이스 무결성을 보장 할 수있는 메커니즘입니다. – kgrittn

0

세이브 포인트를 사용할 수 있습니다. manual에서 :

BEGIN; 
    INSERT INTO table1 VALUES (1); 
    SAVEPOINT my_savepoint; 
     INSERT INTO table1 VALUES (2); 
    ROLLBACK TO SAVEPOINT my_savepoint; 
    INSERT INTO table1 VALUES (3); 
COMMIT; 

당신은 여전히 ​​귀하의 의견을 확인해야하지만 지금은 하나의 트랜잭션 내에서 롤백 할 수 있습니다. 트랜잭션을 사용하면 커밋이 적기 때문에 데이터베이스를 더 빠르게 만들 수 있습니다.

+0

+1 - 먼 곳으로 가야하고 거래가 매우 오래 걸리고/또는 코스의 많은 테이블을 잠그고 필요한 것보다 더 많은 동시 작업을 차단하기 시작하지 않는 한. 그런 다음 작은 트랜잭션으로 분할해야합니다 (현명한 방법으로). –

+0

항상 그렇듯이 작업 부하에 따라 다릅니다. –

+0

질문에서 하나의 항목이 유효성 검사에 실패하면 아무 것도 적용되지 않아야한다고 명시 적으로 명시되어 있습니다. 그래서이 제안은 완전히 비생산적입니다. – kgrittn

관련 문제