[java] Google Guice와 데이터베이스 트랜잭션 관리하기

Google Guice는 자바 기반의 의존성 주입(Dependency Injection) 프레임워크로, 응용 프로그램의 객체 간의 의존성을 관리하는 데 도움을 줍니다. 이번 글에서는 Google Guice를 사용하여 데이터베이스 트랜잭션을 관리하는 방법을 알아보겠습니다.

Guice 설정

먼저, 프로젝트에 Guice를 추가해야 합니다. Maven을 사용한다면 pom.xml 파일에 다음 의존성을 추가합니다:

<dependencies>
    ...
    <dependency>
        <groupId>com.google.inject</groupId>
        <artifactId>guice</artifactId>
        <version>5.0.1</version>
    </dependency>
    ...
</dependencies>

Guice를 추가한 후, Guice 모듈을 구성해야 합니다. TransactionModule 클래스를 생성하여 다음과 같이 작성해보겠습니다:

import com.google.inject.AbstractModule;
import com.google.inject.matcher.Matchers;
import javax.inject.Singleton;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class TransactionModule extends AbstractModule {
    
    @Override
    protected void configure() {
        // EntityManagerFactory 설정
        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("your-persistence-unit-name");
        bind(EntityManagerFactory.class).toInstance(entityManagerFactory);

        // EntityManager 설정
        bind(EntityManager.class).toProvider(EntityManagerProvider.class).in(Singleton.class);
        
        // 트랜잭션 관리를 위해 TransactionInterceptor 적용
        TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
        requestInjection(transactionInterceptor);
        bindInterceptor(Matchers.any(), Matchers.annotatedWith(Transactional.class), transactionInterceptor);
    }
}

위의 TransactionModule 클래스에서는 EntityManager와 트랜잭션을 관리하기 위한 인터셉터(TransactionInterceptor)를 설정합니다. 또한 EntityManagerFactorySingleton으로 바인딩하고, EntityManagerEntityManagerProvider를 통해 바인딩합니다.

트랜잭션 어노테이션

Guice에서 제공하는 @Transactional 어노테이션을 사용하여 트랜잭션을 적용할 메서드를 표시합니다. @Transactional 어노테이션을 사용하려면 다음과 같이 작성해야 합니다:

import com.google.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;

public class TransactionalService {

    private final EntityManager entityManager;

    @Inject
    public TransactionalService(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    @Transactional
    public void performTransactionalOperation() {
        // 트랜잭션 처리를 위한 비즈니스 로직
    }
}

위의 예제에서는 EntityManager를 생성자 주입을 통해 인스턴스화합니다. 그리고 performTransactionalOperation 메서드에 @Transactional 어노테이션을 붙여 트랜잭션을 적용합니다.

트랜잭션 실행

실제로 트랜잭션을 실행하려면 다음과 같이 TransactionModule을 사용하여 Guice Injector를 생성하고, 해당 인젝터에서 TransactionalService를 가져와야 합니다:

import com.google.inject.Guice;
import com.google.inject.Injector;

public class Main {
    
    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new TransactionModule());
        TransactionalService service = injector.getInstance(TransactionalService.class);
        
        // 트랜잭션 실행
        service.performTransactionalOperation();
    }
}

위의 예제에서는 TransactionModule을 사용하여 Guice Injector를 생성하고, TransactionalService를 가져와서 트랜잭션을 실행합니다.

이제 Guice를 사용하여 데이터베이스 트랜잭션을 손쉽게 관리할 수 있습니다. Guice의 장점은 응용 프로그램에 대한 의존성 관리를 단순화하고, 트랜잭션을 적용하는 데 도움을 준다는 점입니다.

더 자세한 정보는 Google Guice 공식 문서를 참조하세요.