그동안 짠 로직은 모두 select 여서 DB 에 변화를 주지도 않고, return 도 확실하게 해주는 쿼리만 사용했다.
'주문하기' 기능을 구현하면서, 다른 동기들이 일찍이 했던 고민을 시작했다.
우선 순서는 아래와 같다.
1. SELECT - 구매하고자 하는 상품이 판매중인지, 등등을 확인
2. SELECT - 구매하고자 하는 상품의 option 들을 보여줌 (색상과 사이즈 각 각)
3. INSERT - 구매 가능한 경우, 우선 구매자 정보를 저장해줌
4. INSERT - 앞서 저장된 구매자의 id 값을 받아서 order를 만들어줌
5. INSERT - 바로 앞에서 저장된 order 의 id를 받아서 detail_order 를 만들어줌
6. UPDATE - 주문이 완료되고, 재고를 관리하는 경우에는 재고수량을 줄여줌
1, 2 단계에서는 문제가 없었으나, 사실 3까지도 괜찮은데 3->4 로 데이터를 넘겨주어야 하기 때문에 고민이 되었다.
다른 글들을 (자세히는 아니고) 찾아본 결과, lastrowid
를 사용하여 id값을 받아오는 경우가 왕왕 있다.
그런데 사실 우리 서버에는 나밖에 접속하지 않지만, 실제 서비스에서는 수 많은 유저들이 수 많은 데이터를 생성하고 있기 때문에 lastrowid
를 사용하고 싶지 않았다.
결국 크게 나아진것은 아니지만, 최소 같은 api를 누군가가 동시에 사용하지 않는다고 전제를 조금 줄여서 MAX(id) 를 사용하게 되었다.
class OrderDao:
def save_receiver_info(self,
db_connection,
buyer_name,
contact,
zip_code,
street_address,
detail_address
):
with db_connection.cursor(pymysql.cursors.DictCursor) as cursor:
insert_query = '''
INSERT INTO receivers(
name,
contact,
zip_code,
street_address,
detail_address)
VALUES(
%s,
%s,
%s,
%s,
%s
)
'''
row = cursor.execute(insert_query,
(
buyer_name,
contact,
zip_code,
street_address,
detail_address
)
)
select_query =
"""
SELECT MAX(id) FROM receivers
"""
row = cursor.execute(select_query)
row = cursor.fetchone()
이렇게 되면 service 단에서 다음과 같이 사용할 수 있게 된다.
receiver_info = (위의 함수 실행)
receiver_id = receiver_info['MAX(id)']