2008-10-22 7 views

답변

8

오라클을 믿는다면, 전혀 그렇지 않습니다. 오라클이이를 피하기 위해 많은 노력을 기울 였기 때문입니다.

독자는 작성자와 작성자가 독자를 차단할 수 있고 작성자는 모든 독자가 작성하기 전에 행을 완료해야만 대기해야한다는 점이 문제입니다. 그것은 쓰기 과정과 발신자를 지연시킵니다. 독점 잠금 (쓰기 용)은 트랜잭션을 롤백해야 할 경우를 대비하여 트랜잭션이 끝날 때까지 보류됩니다. 트랜잭션이 커밋 될 때까지 새 값을 보는 다른 트랜잭션을 중지합니다.

너무 많은 경합이 없으면 잠금은 일반적으로 좋으며 모든 동시 프로그래밍과 동일합니다. 행/페이지/테이블에 대해 너무 많은 경합이있는 경우 (많은 데이터베이스 서버가 전체 DB 잠금을 수행하지는 않음) 트랜잭션이 동시에 발생하지 않고 차례로 실행됩니다.

오라클은 행 버전 관리를 사용합니다. 오라클은이를 작성하기 위해 행을 잠그지 않고 대신 새로운 버전의 행을 작성합니다.읽기를 반복해야하는 독자는 읽은 행의 버전을 기억합니다. 다만, 독해를 기억하고있는 독자가,이 트랜잭션 (transaction)가 읽어 내었 기 때문에, 다른 라이터에 의해 갱신 된 행을 갱신하려고하면 (자) 에러가 발생합니다. 이것은 분실 한 갱신을 멈추기위한 것이다. 행을 업데이트 할 수 있도록하려면 SELECT가 FOR UPDATE라고해야합니다. 그렇게하면 잠금이 걸립니다. 한 번에 하나의 트랜잭션 만 FOR UPDATE 행을 보유 할 수 있으며 충돌하는 트랜잭션이 대기해야합니다.

SQL Server 2005 이상은 행 버전 관리의 이름 인 스냅 샷 격리를 지원합니다. 다시 읽은 일부 데이터를 업데이트해야하는 경우 SQL Server에서 WITH (UPDLOCK)을 사용하여 업데이트 잠금을 요청해야합니다.

잠금에 대한 추가 문제는 교착 상태의 가능성입니다. 이는 단순히 두 개의 트랜잭션이 각각 다른 리소스가 필요로하는 리소스에 대한 잠금을 유지하는 경우이거나 일반적으로 트랜잭션의주기가 서로 진행해야하는 잠금을 유지하는 경우입니다. 데이터베이스 서버는 일반적으로이 교착 상태를 감지하고 트랜잭션 중 하나를 종료하고 다시 롤백합니다. 그러면 작업을 다시 시도해야합니다. 동일한 행을 수정하는 여러 개의 동시 트랜잭션이있는 경우에는 교착 상태가 발생할 수 있습니다. 행이 다른 순서로 터치되면 교착 상태가 발생합니다. 데이터베이스 서버가 사용할 순서를 강제하는 것은 매우 어렵습니다 (일반적으로 옵티마이 저가 가장 빠른 순서를 선택하기를 원하며, 이는 서로 다른 쿼리에서 반드시 일치하지는 않습니다).

일반적으로 나는 스레딩과 마찬가지로 잠금을 사용하여 확장 성 문제를 일으키고 있다는 것을 증명할 수있을 때까지 잠금을 해제하고 가장 중요한 섹션에 잠금을 해제하는 방법을 제안합니다.

1

나는 그것이 "아래로"모든 방법으로 응용 프로그램을 더 복잡하게 만들기 때문에 생각하지 않습니다. 대부분의 언어는 뛰어난 동시성 처리 기술을 가지고 있으며, 심지어 가장 좋은 방법은 "기본적으로"동시성을 처리 할 수있는 코드를 작성하는 것입니다. 이 http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html

+0

"기본적으로"동시성을 처리 할 수있는 코드 ... 어떻게 제안하나요? – Graviton

+0

나는 그가 프로그래밍 언어 나 java.util.concurrent와 같은 라이브러리의 기능을 사용한다는 것을 의미한다고 생각한다. –

+0

예. 또한 http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html을 참조하십시오. – Rolf

0

는 응용 프로그램에서 동시성을 처리하기 위해 의미합니까, 또는 데이터베이스와 발생하는 동시성 문제를 해결하기 위해 : 자바 동시성에 대한 추가 정보를 원하시면

. 전자의 경우, 좋은 접근 방식으로 나를 공격하지 않습니다. 후자의 경우 스키마를 다시 엔지니어링하지 않고 이것이 유일한 대답 일 수 있습니다.

1

테이블 잠금 또는 행 잠금과 달리 데이터베이스 잠금은 병행 성을 처리하는 나쁜 방법입니다. 그것은 동시성을 배제한다.

+0

답변을 자세히 설명해 주시겠습니까? 그것 때문에 그것을 다루는 나쁜 방법입니다. – DOK

+0

나는 그의 관점이 당신이 데이터베이스를 잠그는 것이고, 당신은 동시성이 없다고 생각한다. –

+0

@ dok1 : Mitchel이 맞습니다. 데이터베이스를 독점 모드로 잠그면 동시 액세스가 전혀 없습니다. 읽기 전용 모드로 데이터베이스를 잠그면 여러 사람이 데이터베이스를 읽을 수 있지만 아무도 데이터베이스를 수정할 수 없습니다. (나는 데이터베이스에 대해 독점적 인 락을 제공하는 DBMS를 알고있다.) –

2

먼저 목표를 정의해야합니다. 동시 요청의 경우 마지막 사용자 또는 첫 번째 사용자를 얻고 싶습니까? 데이터베이스 잠금은 확실히 나쁜 방법입니다. 가능한 한 늦게 테이블/행을 잠그고 잠김 잠금을 해제하십시오.

1

직접 DMBS 잠금을 코딩해야하는 많은 대안이 있습니다. 어떤 종류의 잠금은 실제로 항상 발생합니다 (원자 적 동작 등). 그러나 핵심은 당신이하지 않아도되고 싶지 않다는 것입니다. 철학자들과 식사를 같이하고 싶지 않은 경우에는 식사를하고 싶지 않습니다. 트랜잭션은 잠금을 해제하는 한 가지 방법이지만 대부분 커밋에 사용됩니다. 레코드가 더럽다는 것을 나타내는 필드를 사용하면 (더티 비트 패턴) 다른 방법으로, 원자 접근 방식으로 그렇게하고 있는지 확인하십시오. 언어는 종종 이전 게시물에서 참조한 적절한 해결책을 가지고 있지만 언어는 일반적으로 응용 프로그램, 프로세스 처리, 수준 동시성 및 경우에 따라서는 동시성 이 데이터베이스에서이어야합니다. 나는 당신에게 풍부한 응용 프로그램 계층이 있다고 가정하고 싶지 않지만, 그렇게한다면 당신을 위해 이것을 처리하는 많은 추상화 계층이있다. Oracle by TopLink는 무료이며 추상화, 더티 비트 (dirty bit), 캐싱 및 지연 잠금 (lazy locking)을 통해 데이터베이스 동시성 문제를 관리하는 데 도움이되는 Hibernate의보다 강력한 형제입니다. 학교 또는 개인 프로젝트를 코딩하지 않는 한 실제로 이러한 것을 구현하고 싶지는 않습니다. 문제를 이해하고 거인의 어깨에 서십시오.

관련 문제