XML로 트랜잭션 설정
Spring 트랜잭션 관리를 XML로 구성하려면, applicationContext.xml 또는 spring-config.xml 같은 스프링 설정 파일을 사용하여 트랜잭션 관리 설정을 추가해야 합니다.
기본설정
- Hibernate 및 DataSource 설정: Hibernate SessionFactory 및 데이터 소스를 설정합니다.
- 트랜잭션 관리 설정: 트랜잭션 관리자를 정의하고, 트랜잭션이 적용될 범위를 지정합니다.
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 데이터 소스 설정 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:XE"/>
<property name="username" value="your_username"/>
<property name="password" value="your_password"/>
</bean>
<!-- Hibernate SessionFactory 설정 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.kosta.entity"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
<!-- 트랜잭션 관리 설정 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- 트랜잭션 어드바이스 정의 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 모든 public 메서드는 트랜잭션을 적용 -->
<tx:method name="*"/>
<!-- 읽기 전용 트랜잭션 (SELECT 쿼리 전용) -->
<tx:method name="find*" read-only="true"/>
<tx:method name="get*" read-only="true"/>
<!-- 예외 발생 시 롤백 (기본적으로 모든 메서드에 적용) -->
<tx:method name="*" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
<!-- AOP 설정을 통한 트랜잭션 적용 -->
<aop:config>
<!-- 특정 패키지의 서비스 레이어에 트랜잭션 적용 -->
<aop:pointcut id="serviceLayer"
expression="execution(* com.kosta.service.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceLayer"/>
</aop:config>
</beans>
주요 설정 설명
데이터 소스(dataSource): org.apache.commons.dbcp.BasicDataSource를 사용하여 데이터베이스 연결 풀을 설정합니다. 여기서 driverClassName, url, username, password 속성을 설정해야 합니다.
SessionFactory(sessionFactory): Hibernate LocalSessionFactoryBean을 사용하여 세션 팩토리를 설정합니다. dataSource 및 hibernateProperties를 설정하고, 엔티티 클래스가 위치한 패키지를 packagesToScan 속성에 지정합니다.
트랜잭션 관리자(transactionManager): HibernateTransactionManager를 사용하여 Hibernate와 트랜잭션을 관리합니다. sessionFactory를 참조하도록 설정합니다.
트랜잭션 어드바이스(tx:advice): 트랜잭션이 적용될 메서드와 속성을 정의합니다. 여기서 모든 메서드에 대해 기본적으로 트랜잭션을 적용하고, 특정 패턴의 메서드(find*, get*)는 읽기 전용으로 설정합니다.
AOP 설정(aop:config): 트랜잭션이 적용될 서비스 레이어를 정의합니다. serviceLayer라는 포인트컷을 정의하고, com.kosta.service 패키지의 모든 메서드에 대해 트랜잭션을 적용합니다.
추가 설정 설명
스프링 AOP: 트랜잭션 관리는 스프링의 AOP를 사용하여 구현됩니다. 스프링 AOP를 활성화하려면 aop:config 설정을 사용해야 합니다.
읽기 전용 트랜잭션: 데이터베이스 읽기 전용 작업에 대해 성능 최적화를 위해 read-only="true" 설정을 사용할 수 있습니다.
Rollback 정책: 특정 예외가 발생했을 때 트랜잭션을 롤백할지 여부를 rollback-for 속성을 통해 정의할 수 있습니다.
Spring 트랜잭션 Annotation
XML 설정에 비해 더 간결하고 코드 중심적인 접근 방법입니다.
어노테이션 기반 트랜잭션 관리는 주로 @Transactional 어노테이션을 사용하여 구현됩니다.
이 방법은 유지보수가 쉽고, 코드의 특정 부분에 직접 트랜잭션 설정을 적용할 수 있어 매우 유용합니다
Spring 트랜잭션 Annotation 설정
트랜잭션 관리 활성화:
Java Config 클래스에서 @EnableTransactionManagement 어노테이션을 사용하여 트랜잭션 관리를 활성화합니다.
트랜잭션 관리자를 설정:
@Bean 메서드를 통해 트랜잭션 관리자를 설정합니다.
트랜잭션을 적용할 메서드에 @Transactional 어노테이션을 추가:
트랜잭션이 필요하거나 롤백 조건을 지정할 메서드 또는 클래스에 @Transactional 어노테이션을 사용합니다.
Java Config 클래스 설정
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableTransactionManagement;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = "com.kosta")
public class AppConfig {
// DataSource 설정
@Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
dataSource.setUrl("jdbc:oracle:thin:@localhost:1521:XE");
dataSource.setUsername("your_username");
dataSource.setPassword("your_password");
return dataSource;
}
// Hibernate SessionFactory 설정
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan("com.kosta.entity");
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
// Hibernate 관련 속성 설정
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.format_sql", "true");
return properties;
}
// 트랜잭션 매니저 설정
@Bean
public PlatformTransactionManager transactionManager() {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource());
return transactionManager;
}
}
서비스 클래스에서 @Trasacational 사용
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.kosta.entity.User;
import com.kosta.dao.UserDao;
@Service
public class UserService {
private final UserDao userDao;
public UserService(UserDao userDao) {
this.userDao = userDao;
}
@Transactional
public void saveUser(User user) {
userDao.save(user);
}
@Transactional(readOnly = true)
public User getUserById(Long id) {
return userDao.findById(id);
}
@Transactional(rollbackFor = Exception.class)
public void updateUser(User user) throws Exception {
userDao.update(user);
if (someCondition()) {
throw new Exception("Rollback example");
}
}
private boolean someCondition() {
// 어떤 조건이 롤백을 유발하는지 결정
return true;
}
}
주요 어노테이션 설명
@EnableTransactionManagement:
Spring 컨텍스트에서 트랜잭션 관리 기능을 활성화합니다. 이 어노테이션은 Java Config 클래스에 추가되어야 합니다.
@Transactional:
메서드 또는 클래스 레벨에서 트랜잭션 동작을 지정합니다. 이 어노테이션은 다음과 같은 속성을 가질 수 있습니다:
- propagation: 트랜잭션 전파 행동을 지정합니다 (기본값: REQUIRED).
- isolation: 트랜잭션 격리 수준을 지정합니다 (기본값: DEFAULT).
- timeout: 트랜잭션이 완료될 때까지의 시간을 초 단위로 지정합니다.
- readOnly: 트랜잭션을 읽기 전용으로 설정할지 여부를 지정합니다 (기본값: false).
- rollbackFor: 특정 예외가 발생했을 때 롤백을 유발하는 예외 타입을 지정합니다.
- noRollbackFor: 특정 예외가 발생해도 롤백을 유발하지 않는 예외 타입을 지정합니다.
참고사항
- AOP 및 프록시 사용: @Transactional 어노테이션은 AOP를 사용하여 구현됩니다. 따라서 프록시가 올바르게 설정되어 있는지 확인해야 합니다.
- Java Config와 XML 설정의 혼합 사용: 필요에 따라 Java Config와 XML 설정을 혼합하여 사용할 수 있습니다. 예를 들어, 트랜잭션 관리는 Java Config로 설정하고, 나머지 설정은 XML 파일에 둘 수 있습니다.
트랜잭션 AOP
Spring에서 트랜잭션을 관리할 때, AOP(Aspect-Oriented Programming)를 사용하면 트랜잭션 관련 로직을 비즈니스 로직에서 분리하여 보다 모듈화된 코드를 작성할 수 있습니다.
트랜잭션 AOP는 주로 트랜잭션 경계(transaction boundary)를 선언적으로 정의하고, 트랜잭션 관리 로직을 자동으로 처리할 수 있도록 돕습니다.
트랜잭션 AOP는 @Transactional 어노테이션을 사용하여 메서드 또는 클래스 수준에서 트랜잭션을 선언할 수 있으며, 이를 통해 트랜잭션의 시작과 종료, 롤백 조건 등을 지정할 수 있습니다.
Java Config 사용
Config설정에서 @EnableTransactionManagement 어노테이션을 달아, 트랜잭션 관리 기능을 활성화하고 @Transactional 어노테이션을 달아 트랜잭션 경계를 지정합니다.
Config에서 datasource, sessionfactory, property(sql관련 설정), Transaction Manager 설정을 합니다.
'KOSTA : 클라우드 네이티브 애플리케이션 개발 전문가 양성과정' 카테고리의 다른 글
07/03 56일차 Spring/ OAuth (1) | 2024.07.03 |
---|---|
07/01 54일차 Spring/ JPA (0) | 2024.07.01 |
06/27 52일차 Spring/ Mybatis-Spring (0) | 2024.06.27 |
06/24 49일차 Spring/ Mybatis (0) | 2024.06.24 |
06/21 48일차 Spring/ JNDI / Property 파일설정 (0) | 2024.06.21 |