데이터베이스에서 경쟁 조건을 어떻게 테스트합니까?


30

데이터베이스 코드를 작성하여 경쟁 조건이 적용되지 않는지 확인하고 올바른 행이나 테이블을 잠 갔는지 확인하십시오. 그러나 나는 종종 궁금합니다 : 내 코드가 맞습니까? 기존 경쟁 조건을 강제로 표시 할 수 있습니까? 프로덕션 환경에서 발생하면 내 응용 프로그램이 올바르게 작동하는지 확인하고 싶습니다.

나는 일반적으로 어떤 동시 쿼리가 문제를 일으킬 가능성이 있는지 정확히 알고 있지만 올바른 동작이 발생하는지 (예 : 올바른 유형의 잠금을 사용했는지) 올바른 오류가 발생하는지 확인하기 위해 동시 실행을 강제로 수행하는 방법을 모른다 던지는 것 등

참고 : PostgreSQL과 Perl을 사용하므로 이것이 일반적으로 대답 할 수 없다면 아마도 다시 태깅되어야합니다.

업데이트 : 솔루션이 프로그래밍 방식이라면 선호합니다. 그렇게하면 회귀가 없는지 자동 테스트를 작성할 수 있습니다.


"경주 조건"이란 "교착 상태"를 의미합니까?
Gaius

2
@Gaius ... 아니, 나는 그것이 일부 경쟁 조건의 가능한 결과라고 생각하지만
xenoterracide

데이터베이스의 @Gaius 경쟁 조건은 테이블을 생성하기 전에 테이블을 삭제하거나 삽입하기 전에 행을 업데이트하는 것과 같은 작업을 수행합니다. 일반적으로 데이터베이스 외부의 응용 프로그램 논리에 의해 처리된다고 생각합니다.
Mark D

삽입되기 전에 행을 업데이트 하시겠습니까? db 문제를 일으키지 않습니다. 경쟁 조건은 행을 가져 와서 업데이트하는 것과 같지 않지만 행을 가져온 후 업데이트가 처리되기 전에 다른 사용자가 업데이트하는 것과 같습니다.
xenoterracide

1
@MarkD-아니요. 데이터베이스에서 원자 단위 작업 단위를 잘못 캡슐화하여 발생하는 여러 가지 유형의 경쟁 조건이 있습니다. 다음은 예입니다. "경쟁 조건 또는 경쟁 위험은 전자 시스템 또는 프로세스의 결함으로 인해 프로세스의 출력 또는 결과가 예기치 않게 다른 이벤트의 순서 또는 타이밍에 의존합니다 ." ( 출처 )
Nick Chammas 2016 년

답변:


11

나는 항상 T-SQL 모듈을 사용합니다.

기본적 으로 몇 분 동안 두 개 이상의 연결에서 루프로 모듈을 실행하기 만하면됩니다 . 적절한 CPU가있는 SQL Server 상자가 있다고 가정하면 일반적으로 모든 잠재적 인 문제가 몇 분 안에 노출됩니다.

나는 여기여기에 몇 가지 예를 썼습니다 .


4

보통 RDBMS의 명령 행 도구를 사용하여 CLI 인스턴스가 2 개 이상 시작했습니다. 그런 다음 응용 프로그램 계층이 전송하는 SQL 문 을 하나씩 ( 레이스 -RPG처럼 보일 수 있는) 레이스로 하나씩 재생할 수 있습니다 . CLI가 잠금을 해제하고 다른 CLI에서 잠금이 해제 될 때까지 기다리면서 잠금 시스템이 실제로 작동 중임을 느껴야합니다.

진흙처럼 들리면 주저하지 말고 ;-)


단계별 예제를 줄 수 있습니까? 프로그래밍 방식 테스트를 작성하여 동일한 작업을 수행 할 수 있습니까?
xenoterracide

1

경쟁 조건에는 여러 개의 실행 스레드가 필요하므로이를 단위 테스트하려면 하나 이상의 스레드를 시작할 수 있어야합니다. Oracle에서는 DBMS_Scheduler를 사용하여 두 번째 사용자를 시뮬레이션하는 프로세스를 실행합니다. PostgreSQL / Perl에 프로그래밍 방식으로 두 번째 프로세스를 시작하는 방법이 있다면 다음과 같은 작업을 수행 할 수 있습니다.

공정 1 공정 2

프로세스 2를 시작하십시오. >>                            
2가 작동하도록 지연하십시오. 
. 행을 잠 그거나 데이터를 변경하십시오.
. 1이 작동하도록 지연하십시오.
행을 잠 그거나 데이터를 변경하십시오. .
올바른 취급이 이루어 졌는지 확인하십시오. .
끝납니다. .
                                                끝납니다.

경쟁 조건을 처리하는 방법과 더 중요하게 경쟁 조건을 테스트하는 방법에 대해 생각하는 것이 좋습니다.


단위 테스트는 매번 정확히 동일한 방식으로 실행되어야하기 때문에 단위 테스트와 같은 테스트를 설명하지 않습니다. 경쟁 조건은 매번 정확히 같은 방식으로 진행되는 것이 아니라 간헐적으로 관련 프로세스에 실패합니다.
AK

@AlexKuznetsov 예기치 않은 경쟁 조건으로 인해 간헐적으로 표시 될 수 있지만 OP는 코드를 처리 할 것으로 예상되는 예상 조건을 나타냅니다. 이러한 특정 조건을 정확하게 재현하고 단위 테스트로 처리를 확인할 수 있습니다.
레이 리펠

-2

행을 잠그는 한 일반적으로 잠금이 설정되어 있지 않을 때 발생하므로 경쟁 조건에 도달해서는 안됩니다.

그러나 한 질문이 너무 오랫동안 질문을 차단하면 교착 상태에 빠질 수 있습니다.

데이터베이스가 커지면 쿼리 시간이 변경 될 수 있으므로 테스트하기가 어렵습니다.

100 000 행의 테스트 데이터로 올바르게 작동하는 쿼리는 10 000 000 행으로 차트에서 사라집니다.

이러한 유형의 문제는 미리 찾기가 매우 어려울 수 있지만 많은 DB에는 느린 쿼리를 식별하는 방법이 있습니다.

이 규칙을 사용하면 충분한 경고로 인해 문제가 발생하는 모든 쿼리를 트랩 할 수 있어야합니다.

당신이 혼자서 잠금을 설정하면 다른 이야기이지만, 나는 도울 수 없습니다.


@darioo lol 나는 아마도 wn이 무언가에 대한 약어라고 생각했습니다 ... idk "자체적으로 잠금을 수행하십시오"라는 의미 ORM이 아닌 경우 ORM 출력이 아닌 코드를 확인했습니다. 오른쪽 잠금. 잠재적 경쟁 조건 시나리오를 테스트 할 수있는 이유 중 하나입니다.
xenoterracide

예, 나는 자신의 것을 의미했으며 일반적으로 데이터베이스 드라이버는 잠금, 행, 테이블 또는 필드를 처리하지만 잠금을 처리하지 않는 일부 DB를 사용할 가능성을 열었습니다.)

.. DB가 자동으로 잠글 행을 알지 못하는 다중 명령문 트랜잭션이 있는지는 확실 select for update합니다. 만약 그렇게했을 경우에는 존재하지 않을 것입니다 ...
xenoterracide
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.