1212import cmf .commitField .global .error .ErrorCode ;
1313import cmf .commitField .global .exception .CustomException ;
1414import lombok .RequiredArgsConstructor ;
15+ import org .redisson .api .RLock ;
16+ import org .redisson .api .RedissonClient ;
1517import org .springframework .data .domain .Page ;
1618import org .springframework .data .domain .Pageable ;
1719import org .springframework .stereotype .Service ;
20+ import org .springframework .transaction .annotation .Isolation ;
1821import org .springframework .transaction .annotation .Transactional ;
1922
2023import java .time .LocalDateTime ;
2124import java .util .ArrayList ;
2225import java .util .List ;
2326import java .util .Objects ;
27+ import java .util .concurrent .TimeUnit ;
2428
2529@ Service
2630@ RequiredArgsConstructor
2731public class ChatRoomServiceImpl implements ChatRoomService {
2832
2933 private final ChatRoomRepository chatRoomRepository ;
34+
35+ private final ChatMessageRepository chatMessageRepository ;
36+
3037 private final UserRepository userRepository ;
38+
3139 private final UserChatRoomRepository userChatRoomRepository ;
32- private final ChatMessageRepository chatMessageRepository ;
40+
41+ private final RedissonClient redissonClient ;
3342
3443 @ Override
3544 @ Transactional
@@ -61,38 +70,6 @@ public void createRoom(ChatRoomRequest chatRoomRequest, Long userId) {
6170 userChatRoomRepository .save (userChatRoom );
6271 }
6372
64- @ Override
65- @ Transactional
66- public void joinRoom (Long roomId , Long userId ) {
67- // μ μ μ‘°ν
68- User findUser = userRepository .findById (userId )
69- .orElseThrow (() -> new CustomException (ErrorCode .NOT_FOUND_USER ));
70-
71- // room μ‘°ν
72- ChatRoom chatRoom = chatRoomRepository .findById (roomId )
73- .orElseThrow (() -> new CustomException (ErrorCode .NOT_FOUND_ROOM ));
74-
75- // νμ¬ μΈμ μ μ‘°ν
76- Long currentUserCount = userChatRoomRepository .countByChatRoomId (roomId );
77- // μ±ν
λ°©μ΄ κ½ μ°Όμ κ²½μ° μμΈ μ²λ¦¬
78- if (currentUserCount >= chatRoom .getUserCountMax ()) {
79- throw new CustomException (ErrorCode .ROOM_USER_FULL );
80- }
81-
82- // μ΄λ―Έ μ°Έμ¬ν λ°©μΈμ§ νμΈ
83- if (userChatRoomRepository .existsByChatRoomIdAndUserId (roomId , userId )) {
84- throw new CustomException (ErrorCode .ALREADY_JOIN_ROOM );
85- }
86-
87-
88- // user_chatroom κ΄κ³ μμ±
89- UserChatRoom userChatRoom = UserChatRoom .builder ()
90- .user (findUser )
91- .chatRoom (chatRoom )
92- .build ();
93- userChatRoomRepository .save (userChatRoom );
94- }
95-
9673 // λ°© μ‘°ν DTO λ³ν λ©μλ μΆμΆ
9774 private static List <ChatRoomDto > getChatRoomDtos (Page <ChatRoom > all ) {
9875 List <ChatRoomDto > chatRoomList = new ArrayList <>();
@@ -110,6 +87,7 @@ private static List<ChatRoomDto> getChatRoomDtos(Page<ChatRoom> all) {
11087 return chatRoomList ;
11188 }
11289
90+
11391 // μ±ν
λ°© μ 체 μ‘°ν
11492 @ Override
11593 @ Transactional (readOnly = true )
@@ -135,12 +113,57 @@ public List<ChatRoomDto> getUserByRoomPartList(Long userId, Pageable pageable) {
135113 return getChatRoomDtos (allByUserIdAndUserChatRooms );
136114 }
137115
116+ @ Override
117+ @ Transactional (isolation = Isolation .READ_UNCOMMITTED )
118+ public void joinRoom (Long roomId , Long userId ) {
119+ RLock lock = redissonClient .getLock ("joinRoomLock:" + roomId );
120+ try {
121+ boolean available = lock .tryLock (1 , TimeUnit .SECONDS );
122+
123+ if (!available ) {
124+ throw new CustomException (ErrorCode .FAILED_GET_LOCK );
125+ }
126+ // μ μ μ‘°ν
127+ User findUser = getUser (userId );
128+
129+ // room μ‘°ν
130+ ChatRoom chatRoom = chatRoomRepository .findById (roomId ) // lock (κΈ°μ‘΄)
131+ .orElseThrow (() -> new CustomException (ErrorCode .NOT_FOUND_ROOM ));
132+
133+ // user_chatroom νμ¬ μΈμ μΉ΄μ΄νΈ (λΉμ¦λμ€ λ‘μ§)
134+ Long currentUserCount = userChatRoomRepository .countNonLockByChatRoomId (roomId ); // lock (κΈ°μ‘΄)
135+
136+ List <Long > userChatRoomByChatRoomId = userChatRoomRepository
137+ .findUserChatRoomByChatRoom_Id (roomId );
138+
139+ if (userChatRoomByChatRoomId .contains (userId )) {
140+ throw new CustomException (ErrorCode .ALREADY_JOIN_ROOM );
141+ }
142+
143+ // chatroom μ
μ₯
144+ if (currentUserCount >= chatRoom .getUserCountMax ()) {
145+ throw new CustomException (ErrorCode .ROOM_USER_FULL );
146+ }
147+
148+ UserChatRoom userChatRoom = UserChatRoom .builder ()
149+ .user (findUser )
150+ .chatRoom (chatRoom )
151+ .build ();
152+ userChatRoomRepository .save (userChatRoom );
153+ // λΉμ¦λμ€ λ‘μ§ λ
154+ } catch (InterruptedException e ) {
155+ throw new CustomException (ErrorCode .FAILED_GET_LOCK );
156+ } finally {
157+ lock .unlock ();
158+ }
159+
160+
161+ }
162+
138163 @ Override
139164 @ Transactional
140165 public void outRoom (Long userId , Long roomId ) {
141- ChatRoom room = chatRoomRepository
142- .findChatRoomById (roomId )
143- .orElseThrow (() -> new CustomException (ErrorCode .NO_ROOM_FOUND ));
166+ ChatRoom room = getChatRoom (roomId );
144167 // λ°©μ₯μ΄ μλλΌλ©΄
145168 if (!Objects .equals (room .getRoomCreator (), userId )) {
146169 userChatRoomRepository .deleteUserChatRoomByChatRoom_IdAndUserId (roomId , userId );
@@ -153,13 +176,10 @@ public void outRoom(Long userId, Long roomId) {
153176
154177 }
155178
156-
157179 @ Override
158180 @ Transactional
159181 public void deleteRoom (Long userId , Long roomId ) {
160- ChatRoom room = chatRoomRepository
161- .findChatRoomById (roomId )
162- .orElseThrow (() -> new CustomException (ErrorCode .NO_ROOM ));
182+ ChatRoom room = getChatRoom (roomId );
163183 //λ°©μ₯μ΄ μλ κ²½μ°, μμ λΆκ°
164184 if (!Objects .equals (room .getRoomCreator (), userId )) {
165185 throw new CustomException (ErrorCode .NOT_ROOM_CREATOR );
@@ -169,8 +189,19 @@ public void deleteRoom(Long userId, Long roomId) {
169189 userChatRoomRepository .deleteUserChatRoomByChatRoom_Id (roomId );
170190 chatRoomRepository .deleteById (roomId );
171191
172- }
192+ }
193+
194+ private User getUser (Long userId ) {
195+ return userRepository .findById (userId )
196+ .orElseThrow (() -> new CustomException (ErrorCode .NOT_FOUND_USER ));
197+ }
173198
174199
200+ private ChatRoom getChatRoom (Long roomId ) {
201+ return chatRoomRepository
202+ .findChatRoomById (roomId )
203+ .orElseThrow (() -> new CustomException (ErrorCode .NONE_ROOM ));
204+
205+ }
175206
176207}
0 commit comments