레일 3.2.3을 사용하는 응용 프로그램을 실행하고 tinyTDS를 사용하여 MS SQL Sever 인스턴스 위에 연결합니다. 응용 프로그램은 유니콘을 사용하여 4 개의 프로세스가있는 다중 스레드입니다. 문제는 응용 프로그램이 데이터베이스의 필드를 사용하여 각 요청에 고유 계정 번호를 할당하기 위해 증가해야하는 번호를 저장한다는 것입니다. 응용 프로그램을 로컬에서 실행할 때 멀티 스레드가 아니기 때문에 문제가 없습니다.DB에서 증분 값을 저장하는 동안 MS SQL에서 레일스 동시성 문제가 발생했습니다
유니콘을 사용하여 준비 환경에서 실행 중이며 응용 프로그램에 여러 개의 동시 요청이 발생할 때마다 10 명 중 1 명이 중복 카드 번호와 함께 다시 나타납니다. 나는 다음을 시도했다.
레거시 코드
row = CardValue.find_by_name("next_card_number") \ or raise "Missing next_card_number row in card_values table"
next_card_number = row.value
row.value = (next_card_number.to_i + 1).to_s
row.save!
return next_card_number
레거시 코드 + 거래
CardValue.transaction do
row = CardValue.find_by_name("next_card_number") \ or raise "Missing next_card_number row in card_values table"
next_card_number = row.value
row.value = (next_card_number.to_i + 1).to_s
row.save!
return next_card_number
end
결과 : 효과 없음
레거시 코드 + with_lock
CardValue.with_lock do
row = CardValue.find_by_name("next_card_number") \ or raise "Missing next_card_number row in card_values table"
next_card_number = row.value
row.value = (next_card_number.to_i + 1).to_s
row.save!
return next_card_number
end
결과 : with_lock이
레거시 코드 + with_lock
CardValue.transaction do
lock!
row = CardValue.find_by_name("next_card_number") \ or raise "Missing next_card_number row in card_values table"
next_card_number = row.value
row.value = (next_card_number.to_i + 1).to_s
row.save!
return next_card_number
end
결과 정의되지 않은 것을 오류 : 잠금 오류
레일을 생성하는 것은 레거시 시스템에서 비즈니스 요구 사항입니다. 레거시 시스템이 다른 시스템에 연결되어 있기 때문입니다. 내가 바꿀 수있는 것이 아닙니다. – ericglasser