
언체크 예외 활용
- 언체크 예외를 활용하여 처리가 불가능 예외에 대하여 무시하고 그 예외를 의존하는 문제를 해결할 수 있음
예)
public class MyDbException extends RuntimeException{
public MyDbException() {
super();
}
public MyDbException(String message) {
super(message);
}
public MyDbException(String message, Throwable cause) {
super(message, cause);
}
public MyDbException(Throwable cause) {
super(cause);
}
}
public interface MemberRepository {
Member save(Member member);
Member findById(String memberId);
void update(String memberId, int money);
void delete(String memberId);
}
public class MemberRepositoryV4_1 implements MemberRepository{
private final DataSource dataSource;
public MemberRepositoryV4_1(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public Member save(Member member) {
String sql = "insert into member(member_id, money) values(?, ?)";
Connection con = null;
PreparedStatement pstmt = null;
try {
con = getConnection();
pstmt = con.prepareStatement(sql);
pstmt.setString(1, member.getMemberId());
pstmt.setInt(2, member.getMoney());
pstmt.executeUpdate();
return member;
} catch(SQLException e) {
throw new MyDbException(e);
} finally {
close(con, pstmt, null);
}
}
public Member findById(String memberId) {
String sql = "select * from member where member_id = ?";
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
con = getConnection();
pstmt = con.prepareStatement(sql);
pstmt.setString(1, memberId);
rs = pstmt.executeQuery();
if(rs.next()) {
Member member = new Member();
member.setMemberId(rs.getString("member_id"));
member.setMoney(rs.getInt("money"));
return member;
} else {
throw new NoSuchElementException("member not found memberId=" + memberId);
}
} catch(SQLException e) {
throw new MyDbException(e);
} finally {
close(con, pstmt, null);
}
}
public Member findById(Connection con, String memberId) {
String sql = "select * from member where member_id = ?";
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = con.prepareStatement(sql);
pstmt.setString(1, memberId);
rs = pstmt.executeQuery();
if(rs.next()) {
Member member = new Member();
member.setMemberId(rs.getString("member_id"));
member.setMoney(rs.getInt("money"));
return member;
} else {
throw new NoSuchElementException("member not found memberId=" + memberId);
}
} catch(SQLException e) {
throw new MyDbException(e);
} finally {
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeStatement(pstmt);
}
}
public void update(String memberId, int money) {
String sql = "update member set money=? where member_id =?";
Connection con = null;
PreparedStatement pstmt = null;
try {
con = getConnection();
pstmt = con.prepareStatement(sql);
pstmt.setInt(1, money);
pstmt.setString(2, memberId);
pstmt.executeUpdate();
} catch(SQLException e) {
throw new MyDbException(e);
} finally {
close(con, pstmt, null);
}
}
public void update(Connection con, String memberId, int money) {
String sql = "update member set money=? where member_id =?";
PreparedStatement pstmt = null;
try {
pstmt = con.prepareStatement(sql);
pstmt.setInt(1, money);
pstmt.setString(2, memberId);
pstmt.executeUpdate();
} catch(SQLException e) {
throw new MyDbException(e);
} finally {
JdbcUtils.closeStatement(pstmt);
}
}
public void delete(String memberId) {
String sql = "delete from member where member_id =?";
Connection con = null;
PreparedStatement pstmt = null;
try {
con = getConnection();
pstmt = con.prepareStatement(sql);
pstmt.setString(1, memberId);
pstmt.executeUpdate();
} catch(SQLException e) {
throw new MyDbException(e);
} finally {
close(con, pstmt, null);
}
}
private void close(Connection con, Statement stmt, ResultSet rs) {
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeStatement(stmt);
DataSourceUtils.releaseConnection(con, dataSource);
}
private Connection getConnection() {
Connection con = DataSourceUtils.getConnection(dataSource);
log.info("set connection={}, class={}", con, con.getClass());
return con;
}
}
@RequiredArgsConstructor
public class MemberServiceV4 {
private final MemberRepository memberRepository;
@Transactional
public void accountTransfer(String fromId, String toId, int money) {
Member fromMember = memberRepository.findById(fromId);
Member toMember = memberRepository.findById(toId);
memberRepository.update(fromId, fromMember.getMoney() - money);
if(toMember.getMemberId().equals("ex")) {
throw new IllegalStateException("이체중 예외 발생");
}
memberRepository.update(toId, toMember.getMoney() + money);
}
}
@Slf4j
@SpringBootTest
class MemberServiceV4Test {
public static final String MEMBER_A = "memberA";
public static final String MEMBER_B = "memberB";
public static final String MEMBER_EX = "ex";
@Autowired
private MemberRepository memberRepository;
@Autowired
private MemberServiceV4 memberService;
@TestConfiguration
@RequiredArgsConstructor
static class TestConfig {
private final DataSource dataSource;
@Bean
MemberRepository memberRepository() {
return new MemberRepositoryV4_1(dataSource);
}
@Bean
MemberServiceV4 memberServiceV4() {
return new MemberServiceV4(memberRepository());
}
}
@AfterEach
void after() {
memberRepository.delete(MEMBER_A);
memberRepository.delete(MEMBER_B);
memberRepository.delete(MEMBER_EX);
}
@Test
void AopCheck() {
log.info("memberService class={}", memberService.getClass());
log.info("memberRepository class={}", memberRepository.getClass());
Assertions.assertThat(AopUtils.isAopProxy(memberService)).isTrue();
Assertions.assertThat(AopUtils.isAopProxy(memberRepository)).isFalse();
}
@Test
@DisplayName("정상 이체")
void accountTransfer() {
Member memberA = new Member(MEMBER_A, 10000);
Member memberB = new Member(MEMBER_B, 10000);
memberRepository.save(memberA);
memberRepository.save(memberB);
memberService.accountTransfer(memberA.getMemberId(), memberB.getMemberId(), 2000);
Member findMemberA = memberRepository.findById(memberA.getMemberId());
Member findMemberB = memberRepository.findById(memberB.getMemberId());
Assertions.assertThat(findMemberA.getMoney()).isEqualTo(8000);
Assertions.assertThat(findMemberB.getMoney()).isEqualTo(12000);
}
@Test
@DisplayName("이체중 예외 발생")
void accountTransferEx() {
Member memberA = new Member(MEMBER_A, 10000);
Member memberEx = new Member(MEMBER_EX, 10000);
memberRepository.save(memberA);
memberRepository.save(memberEx);
Assertions.assertThatThrownBy(() -> memberService.accountTransfer(memberA.getMemberId(), memberEx.getMemberId(), 2000))
.isInstanceOf(IllegalStateException.class);
Member findMemberA = memberRepository.findById(memberA.getMemberId());
Member findMemberEx = memberRepository.findById(memberEx.getMemberId());
Assertions.assertThat(findMemberA.getMoney()).isEqualTo(10000);
Assertions.assertThat(findMemberEx.getMoney()).isEqualTo(10000);
}
}