@Aspect
@Component
public class ConnectionInterceptor {

    private static final Logger log = LoggerFactory.getLogger(ConnectionInterceptor.class);
    private static final boolean isTraceEnabled = log.isTraceEnabled();

    @Autowired
    private SessionFactory sessionFactory;

    @Around("@annotation(kr.hconnect.data.mysql.ReadOnlyConnection)")
    public Object proceed(ProceedingJoinPoint pjp) throws Throwable {

        log.debug("읽기전용 작업을 수행하기 위해 현 connection를 readonly로 설정합니다...");

        SessionImpl session = (SessionImpl) sessionFactory.getCurrentSession();
        Connection connection = session.connection();

        boolean autoCommit = connection.getAutoCommit();
        boolean readOnly = connection.isReadOnly();

        try {
            // MySQL SLAVE 서버에 접속하기 위해 Connection 속성을 설정합니다.
            connection.setAutoCommit(false);
            connection.setReadOnly(true);

            // @ReadOnlyConnection이 선언된 메소드를 실행합니다.
            return pjp.proceed();

        } finally {
            connection.setAutoCommit(autoCommit);
            connection.setReadOnly(readOnly);
            log.debug("읽기전용 작업을 수행하고, connection의 원래 설정으로 재설정했습니다.");
        }
    }
}