아키텍처와 함께

블로그 이미지
by gregorio
  • Total hit
  • Today hit
  • Yesterday hit

Spring Framework에서 CUD에 Transaction에 대해 DB에 데이터를 저장하지 않고 기능이 

정상적으로 동작하는지 확인이 필요한 경우가 있을 수 있다.

이 때 새로운 User Transaction을 정의한 후 모든 Transaction을 Rollback처리하도록 설정하면 가능하다.

 

본 기능에 대해서는 많은 테스트를 수행하지 않았지만, 하나의 테이블에 대한 Insert에 대해서는 정상적으로 

동작하는것을 테스트하였다.

 

Transaction은 일반적으로 서비스 단위에서 시작하지만,  모든 Trasnsaction을 Rollback 처리하기 위한 User

Transaction을 생성을 어디에서 해야할지 정의해야한다.

 

본 예제에서는 User Transaction을 Interceptor에서 정의한 후 해당 Transaction을 Rollback only로 설정하였다.

 

예제 프로그램은 다음과 같다.

 

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class SimulatorInterceptor extends HandlerInterceptorAdapter implements InitializingBean {

private static final Logger LOGGER = LoggerFactory.getLogger(SimulatorInterceptor.class);
private boolean enabled;
private boolean keyEnabled;
private String key;

private PlatformTransactionManager txManager;


@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

String requestUri = ((HttpServletRequest)request).getRequestURI();

String keyValue = (String)request.getParameter(key);
keyValue = keyValue != null ? keyValue : "N";
if (enabled && (keyEnabled && "Y".equalsIgnoreCase(keyValue))) {
LOGGER.info("This [{}] request is for simulation", requestUri);

DefaultTransactionDefinition transDef = new DefaultTransactionDefinition();
transDef.setName("SimulationTx");
transDef.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
transDef.setReadOnly(false);
transDef.setTimeout(30);
try {
/** New transaction **/
TransactionStatus status = txManager.getTransaction(transDef);
if (status.isNewTransaction()) {
LOGGER.warn("This [{}] transaction is created", requestUri);
}

/** Set roll back only **/
status.setRollbackOnly();
LOGGER.warn("This [{}] request is  roll back only", requestUri);
}
catch(Exception ex) {
LOGGER.error(ex.getMessage());
}

}

return super.preHandle(request, response, handler);
}


@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView mav) throws Exception {
SimulatorContextHolder.rollback();
/** Do nothing **/
}


public void setEnabled(boolean enabled) {
this.enabled = enabled;
}


public void setKey(String key) {
this.key = key;
}


public void setKeyEnabled(boolean keyEnabled) {
this.keyEnabled = keyEnabled;
}


public void setTxManager(PlatformTransactionManager txManager) {
this.txManager = txManager;
}


@Override
public void afterPropertiesSet() throws Exception {
if (keyEnabled && key == null) {
this.key = "simulationYn";
}
}
}

1. DefafultTransactionDefinition을 통해 Transaction 이름, Prapagatio, ReadOnly 및 Timeout을 정의한다.

2. TransactionManager를 통해 TransactionStatus를 생성한다.

3. TransactionStatus.setRollbackOnly를 통해 모든 Transaction을 Rollback처리한다.

 

본 예제에서는 Interceptor에서 User Transaction을 REQUIRED로 생성한 후 이후 모든 Transaction이 REQUIRED로

정의되어 있는 경우에 사용이 가능한다.

 

User Transaction 생성 이후 다음 Transaction이 REQUIRED_NEW로 정의되면 정상적으로 모든 Transaction이 Rollback 되지 않는다.

 

 

AND

ARTICLE CATEGORY

분류 전체보기 (56)
Spring Framrwork (33)
Linux (1)
APM (1)
Java (8)
python (0)
ant (1)
chart (1)
OS (1)
tomcat (1)
apache (1)
database (0)

RECENT ARTICLE

RECENT COMMENT

CALENDAR

«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31

ARCHIVE

LINK