본문 바로가기

Study

Spring PSA

Spring PSA 란 무엇일까?
PSA 는 IOC/DI, AOP 와 함께 Spring의 3대 핵심 가치 중 하나다. PSA 는 Portable Service Abstraction 의 약자로, 추상화된 서비스 계층이라는 뜻을 담고 있다. 추상화된 서비스 계층이 무엇이며, 어떤 편의를 가져다 주는지 더 자세히 알아보자.

 

스프링의 3대 핵심 가치를 나타내는 삼각형

 

추상화된 서비스 계층이란 말 그대로, 여러 서비스에 대하여 구체적인 기술들은 내부적으로 숨기고 개발자에게는 추상화된 계층만을 제공함으로써 특정 기술이나 환경에 종속되지 않게끔 하고, 코드에 유연성과 확장성을 부여하는 것을 말한다. 스프링에서는 트랜잭션 처리를 @Transactional 어노테이션 만으로 아주 간단하게 처리하는데, 이 또한 스프링이 제공하는 PSA 의 하나라고 볼 수 있다. 

다음은 기본적인 jdbc 트랜잭션 예제이다. 

public void updateCoffeeSales(HashMap<String, Integer> salesForWeek) throws SQLException {
    String updateString =
      "update COFFEES set SALES = ? where COF_NAME = ?";
    String updateStatement =
      "update COFFEES set TOTAL = TOTAL + ? where COF_NAME = ?";

    try (PreparedStatement updateSales = con.prepareStatement(updateString);
         PreparedStatement updateTotal = con.prepareStatement(updateStatement))
    
    {
      con.setAutoCommit(false);
      for (Map.Entry<String, Integer> e : salesForWeek.entrySet()) {
        updateSales.setInt(1, e.getValue().intValue());
        updateSales.setString(2, e.getKey());
        updateSales.executeUpdate();

        updateTotal.setInt(1, e.getValue().intValue());
        updateTotal.setString(2, e.getKey());
        updateTotal.executeUpdate();
        con.commit();
      }
    } catch (SQLException e) {
      JDBCTutorialUtilities.printSQLException(e);
      if (con != null) {
        try {
          System.err.print("Transaction is being rolled back");
          con.rollback();
        } catch (SQLException excep) {
          JDBCTutorialUtilities.printSQLException(excep);
        }
      }
    }
  }


살펴보면 SQL 이 나가더라도 커밋을 바로 하지 않고, 작업이 끝난 후에 일괄적으로 커밋을 진행하며 예외 발생시 모든 작업을 롤백한다. 일반적으로 트랜잭션 처리를 위해선 이와 같이 조금은 번거로운 코드가 혼합되어야 한다. 그러나 우리는 트랜잭션 처리를 수행할 작업에 @Transactinal 어노테이션을 붙이는 것 만으로 트랜잭션 처리를 할 수 있다. 또 내부적으로 JDBC transaction manager 를 사용할 수도 있고 JPA transaction manager 를 사용할 수도 있다. 러나 우리는 추상화되어 제공된 @Transactional 의 구현체를 바꿔주는 것 만으로 다양한 transaction manager 를 사용할 수 있고, 그 내부 구현은 알지 못하지만 개발을 하는데 문제가 없다. 이것이 추상화된 서비스 계층의 이점이다.

 

Spring MVC 나 Spring WebFlux 의 starter 의존성도 PSA 가 적용된 예라고 할 수 있다. 의존성 설정 파일(build.gradle)에서 starter-web 을 starter-webflux 로 바꿔주기만 하면, 코드의 변경 없이도 Tomcat 환경의 서블릿 스택에서 Netti 환경의 반응형 스택으로 변경 가능하다. 

 

starter-web 의존성 패키지를 webflux 로 변경

 

Netty 서버로 실행환경 변경

 

gradle 파일의 의존성 한 줄만 바꿔 주었을 뿐인데 어플리케이션을 구동하는 서버 자체가 달라졌다. 


이처럼 PSA 는 사용자에게 단순하며 일관성있게 추상화된 인터페이스만을 제공하고, 그 내부 구현을 알지 못해도 간단하게 구현을 바꿀 수 있을 뿐만 아니라 특정 기술에 강하게 결합되지 않고 코드의 이식성과 유지보수성, 유연성을 제공한다.