Управление транзакциями в реализации сервера SOAP - PullRequest
2 голосов
/ 02 августа 2011

У меня есть стандартная веб-служба jax-ws, которая использует Spring для DI и Hibernate для персистентности. Теперь в Spring вы обычно заключаете запрос в специальный фильтр и выполняете beginTransaction() и commit() / rollback() в сеансе Hibernate в зависимости от того, прошло ли выполнение без ошибок или нет.

Однако для мыльного веб-клиента эта цепочка выполнения не используется, и поэтому управление транзакциями не может быть легко настроено подобным образом. Конечно, я также хочу избежать включения каждой из моих @WebMethod реализаций в

session.beginTransaction();
try {
   ... 
   session.commit();
}
catch (RuntimeException e) {
   session.rollback();
   throw e;
}

поэтому я посмотрел на другие возможности. Очевидно, JSR позволяет настроить SOAPHandler (через @HandlerChain), которые перехватывают SOAP-трафик после отправки и до отправки исходящих мыльных сообщений, но мне интересно, нахожусь ли я на правильном пути с этим или делаю это неправильно ...

Ребята, знаете ли вы о других альтернативах?


Я пошел по маршруту SOAPHandler, и, похоже, он хорошо работает:

public class SOAPServiceHandler implements SOAPHandler<SOAPMessageContext>
{
    @Override
    public void close(MessageContext mc)
    {
    }

    @Override
    public boolean handleFault(SOAPMessageContext smc)
    {
        MyHibernateUtil.rollbackTransaction();
        return true;
    }

    @Override
    public boolean handleMessage(SOAPMessageContext smc)
    {
        Session session = MyHibernateUtil.getCurrentSession();
        Boolean outbound = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (!outbound)
        {
            session.beginTransaction();
            session.setFlushMode(FlushMode.COMMIT);
            return true;
        }

        SOAPBody body = null;
        try
        {
            body = smc.getMessage().getSOAPBody();
        }
        catch (SOAPException e)
        {
        }

        session.flush();
        session.setFlushMode(FlushMode.AUTO);

        if (body == null || body.hasFault())
        {
            session.getTransaction().rollback();
        }
        else
        {
            session.getTransaction().commit();
        }

        return true;
    }

    @Override
    public Set<QName> getHeaders()
    {
        return null;
    }
}

Это мой applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:ws="http://jax-ws.dev.java.net/spring/core"
    xmlns:wss="http://jax-ws.dev.java.net/spring/servlet"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
            http://jax-ws.dev.java.net/spring/core
            http://jax-ws.dev.java.net/spring/core.xsd
            http://jax-ws.dev.java.net/spring/servlet
            http://jax-ws.dev.java.net/spring/servlet.xsd"> 

    <bean id="SoapServiceImpl" class="path.to.SOAPServiceImpl" />       
    <bean id="SoapServiceHandler" class="path.to.SOAPServiceHandler" /> 

    <wss:binding url="/soap">
        <wss:service>
            <ws:service bean="#SoapServiceImpl">
                <ws:handlers>
                    <ref bean="SoapServiceHandler" />
                </ws:handlers>
            </ws:service>
        </wss:service>
    </wss:binding>
</beans>

Обратная связь приветствуется!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...