[Project_] FO - 2 (Trouble Shooting)
고유 제약 조건 위반 - P2002
- 처음보는 에러... 어떤 에러일까?
Error Log ▼
Invalid `prisma.inventory.update()` invocation:
code: 'P2002',
clientVersion: '6.0.1',
meta: {
modelName: 'Inventory',
target: 'Inventory_managerId_teamMemberId_isEquipped_key'
}
}
● 왜 발생했는가
- 아이템 장착에 대한 기능을 구현하던 중에 발생한 에러
- 데이터베이스를 정의할 때 설정해둔 Unique 제약 조건이 존재
→ 'Inventory_managerId_teamMemberId_isEquipped_key'
- 해당 제약 조건을 위반 했을 때 해당 에러가 발생함
→ managerId, teamMemberId, isEquipped 필드의 조합이 고유해야 함
- 동일한 매니저(managerId)의 동일한 팀 멤버(teamMemberId)에 대해 이미 장착된
아이템이 존재할 때 또 다른 아이템을 장착 시도를 하여 에러 발생
→ 데이터베이스 설계상 한 멤버가 동시에 하나의 아이템만 장착하도록 제한되어 있음

● 어떻게 해결했는가?
- 아이템 장착 로직에 기존에 장착된 아이템을 해제하지 않고 새 아이템을 장착하려고 시도하여
해당 에러가 발생한 것이다
await prisma.$transaction(async (tx) => {
// 기존 장착 아이템 해제
await tx.inventory.updateMany({
where: {
managerId: manager.managerId,
teamMemberId: Number(teamMemberIds[i]),
isEquipped: true,
},
data: {
isEquipped: false,
teamMemberId: null,
},
});
// 새 아이템 장착
await tx.inventory.update({
where: {
inventoryId: Number(itemIds[i]),
},
data: {
isEquipped: true,
teamMemberId: Number(teamMemberIds[i]),
},
});
});
- 위의 코드 처럼 트랜잭션으로 기존 아이템을 해제 후 장착이 가능하도록 코드를 수정
● 해결이 되었는가?
{
"message": "아이템이 성공적으로 장착되었습니다."
}
- Insomnia 앱으로 API를 실행했을 때 성공적으로 작동함
● 혹시나 Error를 방지하여...
if (
error &&
typeof error === 'object' &&
error.constructor &&
error.constructor.name === 'PrismaClientKnownRequestError'
) {
if (error.code === 'P2002') {
return res.status(409).json({
error: '이미 장착된 아이템이 있습니다. 먼저 해제해 주세요.',
});
}
// 다른 Prisma 관련 에러 처리
return res.status(400).json({
error: '데이터베이스 작업 중 오류가 발생했습니다.',
});
}
// 기타 예상치 못한 에러
res.status(500).json({ error: '서버 내부 오류가 발생했습니다.' });
- 예기치 않은 에러가 발생하여 서버가 작동 중지되는 것을 막기 위해 추가적으로 에러 처리를 했다.
● 결론
- 데이터베이스를 정의할 때 여러 상황을 고려하여 정의해야할 거 같다.
- 세밀한 설정으로 코드를 작성하던 도중에 데이터베이스를 재정의하는 일이 없도록
기획단계에서 자세하게 계획해야겠다는 교훈을 얻었다.