2010-05-10 7 views
2

유효한 데이터가 들어있는 테이블이 있다고 가정합니다. 어떤 식 으로든이 데이터를 수정하고 싶습니다만, 수정시 오류가 발생하면 테이블이 변경되지 않고 메서드가 그 결과를 반환하는지 확인하고 싶습니다.JDBC를 통해 MySQL 문을 원자 적으로 실행하는 좋은 방법이 있습니까?

예를 들어, (이것은 일종의 벙어리 예이지만, 나와 곰이 맺어 졌기 때문에) "이름"열의 모든 항목을 적절하게 대문자로 편집하려고한다고 가정합니다. 어떤 이유로 든 모든 이름에 적절한 대소 문자를 사용하거나 NONE에 대문자를 적절하게 사용하고 싶습니다 (그리고 테이블의 시작 상태는 NONE이하는 것입니다).

테이블에서 일괄 업데이트를 실행하는 이미 구현 된 방법이 있으며 업데이트 중 하나라도 실패하면 모든 변경 사항이 롤백되고 테이블이 변경되지 않습니다.

나는 손으로이 작업을 수행하는 몇 가지 방법을 생각할 수 있지만 (제안은 환영하지만)이 방법으로 사용할 수있는 몇 가지 방법이 있다면 좋을 것입니다. java.sql.statement.executeBatch() 명령을 살펴 봤지만 문서가 어떤 식 으로든 실패하면 내 테이블이 변경되지 않는다고 확신하지는 않습니다.

답변

8

JDBC로 시작했을 때도이 점이 맞았습니다. 데이터베이스와 ACID 보증에 대해 이해 한 것처럼 보였습니다.

시작하기 전에 MySQL storage engine이 트랜잭션을 지원하는지 확인하십시오. MyISAM은 트랜잭션을 지원하지 않지만 InnoDB는 트랜잭션을 지원하지 않습니다.

그런 다음 JDBC autoCommit - Connection.setAutoCommit(false)을 비활성화하십시오. 그렇지 않으면 JDBC는 각 구문을 별도의 트랜잭션으로 실행합니다. 커밋은 전부 또는 두 가지 일이 될 것입니다 - 부분적인 변경은 없습니다. 그런 다음 다양한 업데이트 문을 실행하고 마지막으로 Connection.commit()을 호출하여 트랜잭션을 커밋합니다.

JDBC 트랜잭션에 대한 자세한 내용은 Sun Tutorial을 참조하십시오.

일괄 처리를 사용해도 ACID 보증이 변경되지 않습니다. 귀하는 거래되었거나 그렇지 않습니다! - 일괄 처리는 성능 향상을 위해 여러 개의 명령문을 함께 수집하는 것에 대한 것입니다.

+0

MyISAM 대 InnoDB 힌트의 큰 +1입니다. 이것은 너무 종종 간과됩니다. – BalusC

+0

여기에서 확실하게하기 위해 업데이트 문을 수행하는 적절한 방법은 Statement.executeUpdate (...)를 여러 번 거친 다음 try 블록 내부에 connection.commit()을 호출하고 connection.close() catch 블록 내부(). 일종의 예외가 잡히면 connection.commit()을 호출하지 않아도 테이블을 수정하지 않아도됩니까? – javanix

+1

맞습니다. 커밋되지 않은 트랜잭션과의 연결을 닫으면 트랜잭션이 롤백됩니다. (작지만 중요한 변화 - catch 블록이 아니라 finally 블록에 connection.close()를 넣으십시오.) – mdma

관련 문제