여러 서버에서 실행되지만 금융 거래를 위해 단일 데이터베이스를 공유하는 웹 응용 프로그램을 작성하려고합니다.DBI를 닫으면 postgres 데이터베이스에서 릴리스 잠금이 처리됩니까
간단히 말하면 계정 A에서 B로 금액을 이체하려고합니다.하지만 동일한 계좌에서 송금 요청이 여러 번있을 수 있습니다.
잔액이 절대 음수가 될 수 없으므로 SELECT FOR UPDATE를 사용하여 잔액을 가져 와서 행을 잠그기로했습니다.
나는 데이터베이스에 연결 JDBI을 사용하고 있습니다 : http://jdbi.org/이
코드 흐름은 다음과 같다 :
이컨트롤러 : 여기
DBI dbi = new DBI(datasource);
.....
getAccountBalance();
....
transfer()
는 DOA 부분
public int getAccountBalance(String id) {
Handle h = dbi.open();
try{
return h.createQuery("SELECT balance FROM accounts " +
" WHERE id=:id FOR UPDATE;")
.bind("id", id)
.mapTo(Integer.class)
.first();
} finally {
h.close();
}
}
입니다
DAO가 잔액을 반환하며 잔액 확인을 s 전송이 가능하면 다른 전송 방법을 호출하여 전송할 수 있습니다. 내가 그것을 선택한 행에 대한 잠금을 해제합니다 getAccountBalance()
에 핸들을 닫으면
public void transfer(String fromAccountId, String toAccountId, int transferAmount) {
Handle h = dbi.open();
try{
h.begin();
h.createStatement("UPDATE accounts SET balance = balance - :transferAmount WHERE id = :fromAccountId")
.bind("fromAccountId", fromAccountId)
.bind("transferAmount", transferAmount)
.execute();
h.createStatement("UPDATE accounts SET balance = balance + :transferAmount WHERE id = :toAccountId")
.bind("toAccountId", toAccountId)
.bind("transferAmount", transferAmount)
.execute();
h.commit();
} finally {
h.close();
}
}
내 질문은? 그렇다면 자물쇠를 어떻게 잡을 수 있습니까? 나는 DBI를 처음 사용합니다. 감사합니다.
메서드 A에서 잠금을 만들지 만 메서드 B에서 커밋합니다. 여전히 잠금을 유지합니까? 미안하지만 내가 일찍 제대로 설명하지 않았다면. –
@AmitVig 당신의'dbi' 객체가 무엇인지, 또는'open' 메소드가 무엇인지 모르겠다. 그래서 대답하기가 어렵다. 요점은 * 그것을 획득 한 트랜잭션이 커밋 할 때까지 잠금이 유지된다는 것입니다. 첫 번째 메소드가 여전히 잠금을 유지하고 두 번째 메소드가 별도의 DBI 연결 내에서 호출되면 첫 번째 트랜잭션의 잠금이 무기한으로 차단됩니다. 또는 동일한 연결에서 동일한 열린 트랜잭션 내에서 호출하는 경우 이미 열려있는 트랜잭션에 대한 경고를 표시하지만 그렇지 않으면 잘 작동합니다. –
그래서 야생 *에서 getAccountBalance는 명시 적 트랜잭션을 시작하지 않으므로 자동 커밋됩니다. 따라서 잠금 장치는 명령문이 반환되지 않은 상태로 유지되지 않습니다. 그러나 그것은 당신의 거래 경계가 무엇인지에 대해 몇 가지 추측을하고 있습니다. –