동시에 동일한 레코드에 액세스하여 편집하기 쉬운 테이블에는 lock_version을 사용할 수 있습니다.
소개
Rails Guide 읽고 신경이 쓰였으므로 실제로 만져 보았습니다. 그 메모입니다.
앱에서 A 씨와 B 씨가 같은 레코드를 편집할 때 정확히 같은 타이밍에 같은 레코드에 액세스했을 경우, A 씨가 레코드를 update 하고 그 후 B 씨가 update 하면 B 씨는 A 씨의 편집 내용 확인하지 않고 덮어 씁니다.
이것이 같은 속성의 update라면 아직도 다른 속성인 경우는 편집이 되감아지기 때문에 좋지 않은 상황입니다.
이 문제에 대해 Active Record에서 lock_version을 사용할 수 있습니다.
lock_version은 테이블에 인스턴스의 편집 내역 카운트 역할을하는 열을 추가하고 그 값을 참조하여
lock_version을 이용하면 위와 같은 경우에 두어 에러를 발생시킬 수 있습니다.
사용방법
이용하려면 테이블에 lock_version이라는 열을 작성하면 된다.
t.integer :lock_version, default: 0
동작 확인
p1 = Memo.find(1)
p2 = Memo.find(1)
# => #<Memo id: 1, text: "hello", lock_version: 0>
당연하지만 아직 호출하면 lock_version은 0
그런 다음 p1을 업데이트합니다.
p1.update(text:'good bye')
# => #<Memo id: 1, text: "good bye", lock_version: 1>
SQL (0.3ms) BEGIN
Memo Update (13.4ms) UPDATE `memos` SET `text` = 'good bye', `lock_version` = 1 WHERE `memos`.`id` = 1 AND `memos`.`lock_version` = 0
(3.9ms) COMMIT
look_version이 1로 바뀌었습니다.
또한 update SQL 조건에 lock_version = 0
가 있는지도 확인할 수 있습니다.
다음은 p2를 update 해 봅시다. reload하지 않으므로 p2 인스턴스의 lock_version은 0으로 유지됩니다.
p2.update(text:'say hello')
# => ActiveRecord::StaleObjectError (Attempted to update a stale object: Memo.)
SQL (0.7ms) BEGIN
Memo Update (1.0ms) UPDATE `memos` SET `text` = 'say hello', `lock_version` = 1 WHERE `memos`.`id` = 1 AND `memos`.`lock_version` = 0
(2.4ms) ROLLBACK
제대로 오류가 있습니다.
SQL 자체는 에러 실행해도 나오지 않는다고 생각하기 때문에 rails측에서 영향을 준 행이 없는 것을 트리거로서 에러를 돌려주고 있는 느낌일까?
이번 소스까지 읽지 않기 때문에 읽은 분은 공유해 주시면 도움이됩니다!
동작 확인 (웹)
RailsApi처럼 form에 hidden 매개 변수로 lock_version을 넣으십시오.
이것이 없으면 백엔드에서 lock_version을 비교할 수 없으므로 오류가 발생하지 않습니다.
<input type="hidden" value="2" name="memo[lock_version]" id="memo_lock_version">
상기를 추기해, 같은 레코드를 편집하는 탭을 2개 열어 각각 update 하면 나중에 update 한 분에게 무사 에러가 나왔습니다.
그리고는 또 RailsApi에 있는 대로 에러 핸들링해 대응합시다.
대응하는 방법으로는 여러가지 생각됩니다군요.
이용하려면 테이블에 lock_version이라는 열을 작성하면 된다.
t.integer :lock_version, default: 0
동작 확인
p1 = Memo.find(1)
p2 = Memo.find(1)
# => #<Memo id: 1, text: "hello", lock_version: 0>
당연하지만 아직 호출하면 lock_version은 0
그런 다음 p1을 업데이트합니다.
p1.update(text:'good bye')
# => #<Memo id: 1, text: "good bye", lock_version: 1>
SQL (0.3ms) BEGIN
Memo Update (13.4ms) UPDATE `memos` SET `text` = 'good bye', `lock_version` = 1 WHERE `memos`.`id` = 1 AND `memos`.`lock_version` = 0
(3.9ms) COMMIT
look_version이 1로 바뀌었습니다.
또한 update SQL 조건에 lock_version = 0
가 있는지도 확인할 수 있습니다.
다음은 p2를 update 해 봅시다. reload하지 않으므로 p2 인스턴스의 lock_version은 0으로 유지됩니다.
p2.update(text:'say hello')
# => ActiveRecord::StaleObjectError (Attempted to update a stale object: Memo.)
SQL (0.7ms) BEGIN
Memo Update (1.0ms) UPDATE `memos` SET `text` = 'say hello', `lock_version` = 1 WHERE `memos`.`id` = 1 AND `memos`.`lock_version` = 0
(2.4ms) ROLLBACK
제대로 오류가 있습니다.
SQL 자체는 에러 실행해도 나오지 않는다고 생각하기 때문에 rails측에서 영향을 준 행이 없는 것을 트리거로서 에러를 돌려주고 있는 느낌일까?
이번 소스까지 읽지 않기 때문에 읽은 분은 공유해 주시면 도움이됩니다!
동작 확인 (웹)
RailsApi처럼 form에 hidden 매개 변수로 lock_version을 넣으십시오.
이것이 없으면 백엔드에서 lock_version을 비교할 수 없으므로 오류가 발생하지 않습니다.
<input type="hidden" value="2" name="memo[lock_version]" id="memo_lock_version">
상기를 추기해, 같은 레코드를 편집하는 탭을 2개 열어 각각 update 하면 나중에 update 한 분에게 무사 에러가 나왔습니다.
그리고는 또 RailsApi에 있는 대로 에러 핸들링해 대응합시다.
대응하는 방법으로는 여러가지 생각됩니다군요.
p1 = Memo.find(1)
p2 = Memo.find(1)
# => #<Memo id: 1, text: "hello", lock_version: 0>
p1.update(text:'good bye')
# => #<Memo id: 1, text: "good bye", lock_version: 1>
(0.3ms) BEGIN
Memo Update (13.4ms) UPDATE `memos` SET `text` = 'good bye', `lock_version` = 1 WHERE `memos`.`id` = 1 AND `memos`.`lock_version` = 0
(3.9ms) COMMIT
p2.update(text:'say hello')
# => ActiveRecord::StaleObjectError (Attempted to update a stale object: Memo.)
(0.7ms) BEGIN
Memo Update (1.0ms) UPDATE `memos` SET `text` = 'say hello', `lock_version` = 1 WHERE `memos`.`id` = 1 AND `memos`.`lock_version` = 0
(2.4ms) ROLLBACK
RailsApi처럼 form에 hidden 매개 변수로 lock_version을 넣으십시오.
이것이 없으면 백엔드에서 lock_version을 비교할 수 없으므로 오류가 발생하지 않습니다.
<input type="hidden" value="2" name="memo[lock_version]" id="memo_lock_version">
상기를 추기해, 같은 레코드를 편집하는 탭을 2개 열어 각각 update 하면 나중에 update 한 분에게 무사 에러가 나왔습니다.
그리고는 또 RailsApi에 있는 대로 에러 핸들링해 대응합시다.
대응하는 방법으로는 여러가지 생각됩니다군요.
라든지. 이 부분은 데이터가 앱에서 어떻게 사용되는지에 따라 달라졌다고 했습니까?
마지막으로
나는 실무로 이용한 적이 없기 때문에 「우치에서는 이렇게 하고 있어!」적인 공유를 받을 수 있으면 기쁩니다!
참고 기사
Rails Guide
What is Optimistic Locking
Reference
이 문제에 관하여(동시에 동일한 레코드에 액세스하여 편집하기 쉬운 테이블에는 lock_version을 사용할 수 있습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/abeshi1010/items/60b1e7a6340c23ce1cce
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Rails Guide
What is Optimistic Locking
Reference
이 문제에 관하여(동시에 동일한 레코드에 액세스하여 편집하기 쉬운 테이블에는 lock_version을 사용할 수 있습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/abeshi1010/items/60b1e7a6340c23ce1cce텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)