관리 메뉴

ふたりで

Spring3 @Transactional rollbackFor = {Exception.class} 사용시 참고 본문

Spring

Spring3 @Transactional rollbackFor = {Exception.class} 사용시 참고

graykang 2023. 12. 4. 14:17
728x90
반응형
SMALL

Springboot 프로젝트에서 @Transactional에 rollbackFor = {Exception.class}을 설정하여 예외발생 시 무조건 롤백

되는 로직을 spring3 환경에서 사용을 해보려 하는데 롤백이 안 되는 증상이 있었다.

내가 설정한 환경이 아니었기도 하고 당연히 트랜잭션 설정이 되어 있을 거라 생각하고 @Transactional을 걸었었는데...

내가 만든 개발 환경이 아닐 경우 꼭 spring 기능을 사용해야 할 경우 설정 먼저 되어있는지 확인하는 습관을 가져야겠다..

결론은 Spring3 환경설정에 트랜잭션 설정이 안 돼 있어서 동작을 안 하는 거였다...

 

1. 트랜잭션을 걸어놓은 ServiceImpl 소스 부분:

@Transactional(value = "testTransactionManager", rollbackFor = {Exception.class}) 를 설정하여

해당 로직 내에서 예외가 발생하면 throw new Exception(); 되도록 한다.

	@Override
	@Transactional(value = "testTransactionManager", rollbackFor = {Exception.class})
	public JSONObject deactivateUserInfoPro(UserListVO jsonData) throws Exception {
	    JSONObject json = new JSONObject();
	    try {
			//리스트를 돌면서 파라메터 설정 및 쿼리 실행
		    for(UserListDetailVO martInfo : jsonData.getMartList()) {
                        //리스트에서 queryparams 값설정 생략...
                        //사용자 정보 삭제
                        testDao.deleteAclsssUser(queryparams);
                        //사용자정보 삭제2
                        testDao.deleteUserInfo(queryparams);
                        //사용자 권한정보 삭제
                        //queryparamsauth값설정 생략...
                        testDao.deleteUserinfoAuth(queryparamsauth);
                        //사용자 메뉴제한 데이터 삭제
                        testDao.deleteUserMenuBlockAll(queryparamsauth);
                        //Log 삭제 이력 저장.
                        //maedlogvo값설정 생략...
                        testDao.setAuthUserDeleteLog(maedlogvo);
		    }
		    
		    json.put("code", 0);
		    json.put("message", "삭제 하였습니다.");
			
		} catch (Exception e) {
		    json.put("code", 2);
		    json.put("message", "erroe_삭제를 실패 하였습니다");
		    json.put("error_e", e.getMessage());
		    e.printStackTrace();
		    throw new Exception();
		}
	    
		return json;
	}

 

2. spring3 설정파일 경로 및 구조

728x90
반응형
SMALL

3. tranaction-context.xml의 설정 상태.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

	<context:component-scan base-package="com.graukang" />

	<context:annotation-config/>

	
	<!-- test Database Connection -->
	<bean id="testSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="testDataSource-log" />
		<property name="configLocation" value="classpath:mappers/mybatis-config-base.xml" />
		<property name="mapperLocations" value="classpath:mappers/test/*-mapper.xml" />
	</bean>

	<bean id="testTransactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="testDataSource-log" />
	</bean>
	
	<bean id="testConnection" class="org.mybatis.spring.SqlSessionTemplate" autowire="default">
		<constructor-arg index="0" ref="testSqlSessionFactory" />
	</bean>
	<!-- / test Database Connection -->

</beans>

 

4. appServlet/servlet-context.xml 설정 상태:

아래 3줄을 각 위치에 알맞게 추가 설정을 하였다.

1. xmlns:tx="http://www.springframework.org/schema/tx"

2. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd 

3. <tx:annotation-driven transaction-manager="transactionManager" />

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	
	<!-- Enables the Spring MVC @Controller programming model -->
	<mvc:annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
	<mvc:resources mapping="/resources/**" location="/resources/" />
	
	<mvc:interceptors>
		<bean id="sessionInterceptor" class="com.graykang.comm.interceptor.SessionInterceptor" />
	</mvc:interceptors>

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/" />
		<property name="suffix" value=".jsp" />
	</bean>
	
	<context:component-scan base-package="com.graykang" />
	<context:annotation-config/>
	<tx:annotation-driven transaction-manager="transactionManager" />
	<context:property-placeholder location="classpath:properties/*.properties"/>
</beans>

 

5. root-context.xml 설정 상태:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
	
	<!-- Root Context: defines shared resources visible to all other web components -->
	<aop:aspectj-autoproxy />
	<context:component-scan base-package="com.graykang" />
    <bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <!-- 시스템 환경 변수를 xml에서 일반 변수로 사용할수 있게 해줌 -->
        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
        <property name="searchSystemEnvironment" value="true" />
        <!-- /시스템 환경 변수를 xml에서 일반 변수로 사용할수 있게 해줌 -->
        <property name="locations" value="classpath:properties/application.properties"/>
        <property name="fileEncoding" value="UTF-8"/>
    </bean>

	<!-- Root Context: defines shared resources visible to all other web components -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="${base.upload.max.size}" />
        <property name="maxInMemorySize" value="${base.upload.max.size}" />
        <property name="defaultEncoding" value="utf-8" />
    </bean>	
</beans>

 

6. datasource-context.xml 설정 상태:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	
	
	<!-- test DataSource -->
	<bean id="testDataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${test.db.jdbc.driver}" />
		<property name="url" value="${test.db.jdbc.url}" />
		<property name="username" value="${test.db.jdbc.username}" />
		<property name="password" value="${test.db.jdbc.password}" />
		<property name="poolPreparedStatements" value="true" />
		<property name="validationQuery" value= "SELECT 1" />
		<property name="validationQueryTimeout" value="1000" />
		<property name="maxActive" value="${test.db.jdbc.maxActive}" />
		<property name="minIdle" value="${test.db.jdbc.minIdle}" />
		<property name="maxIdle" value="${test.db.jdbc.maxIdle}" />
		<property name="initialSize" value="${test.db.jdbc.initialSize}" />
	</bean>
	
	<bean id="testDataSource-log" class="net.sf.log4jdbc.Log4jdbcProxyDataSource">
		<constructor-arg ref="testDataSource" />
		<property name="logFormatter">
			<bean class="net.sf.log4jdbc.tools.Log4JdbcCustomFormatter">
				<property name="loggingType">
					<value>MULTI_LINE</value>
				</property>
				<property name="sqlPrefix">
					<value>SQL         :  </value>
				</property>
			</bean>
		</property>
	</bean>
	<!-- / test DataSource -->

	<!-- ETC DataSource -->
	<bean id="etcDataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${etc.db.jdbc.driver}" />
		<property name="url" value="${etc.db.jdbc.url}" />
		<property name="username" value="${etc.db.jdbc.username}" />
		<property name="password" value="${etc.db.jdbc.password}" />
		<property name="poolPreparedStatements" value="true" />
		<property name="validationQuery" value= "SELECT 1" />
		<property name="validationQueryTimeout" value="1000" />
		<property name="maxActive" value="${etc.db.jdbc.maxActive}" />
		<property name="minIdle" value="${etc.db.jdbc.minIdle}" />
		<property name="maxIdle" value="${etc.db.jdbc.maxIdle}" />
		<property name="initialSize" value="${etc.db.jdbc.initialSize}" />
	</bean>
	
	<bean id="etcDataSource-log" class="net.sf.log4jdbc.Log4jdbcProxyDataSource">
		<constructor-arg ref="etcDataSource" />
		<property name="logFormatter">
			<bean class="net.sf.log4jdbc.tools.Log4JdbcCustomFormatter">
				<property name="loggingType">
					<value>MULTI_LINE</value>
				</property>
				<property name="sqlPrefix">
					<value>SQL         :  </value>
				</property>
			</bean>
		</property>
	</bean>
	<!-- / ETC DataSource -->
</beans>
728x90
반응형
LIST
Comments