Безопасность потоков в веб-сервисе JAX-WS (метро на glassfish3) - PullRequest
0 голосов
/ 13 ноября 2011

Мой бизнес-уровень реализован на glassfish3 с веб-сервисами поверх стека метро.

Чтобы легко обрабатывать транзакции, мы используем логический обработчик, который вызывается при каждом вызове, закрытии или сбое одного запроса.

В методах close и fault мы проверяем, остались ли какие-либо транзакции открытыми, и откатываем их.

, чтобы сделать это, мы используем threadlocal, но, конечно, это работает, только если логический обработчик работает в том же потоке конкретного веб-сервисакласс.

public class WebServiceMessageHandler implements LogicalHandler<LogicalMessageContext>  
@Override
public void close(MessageContext context)
{
    DataLayerTransactionManager.RollBackTransactions();         
}

@Override
public boolean handleFault(LogicalMessageContext context)
{
    DataLayerTransactionManager.RollBackTransactions();

    return true;
}



    public class DataLayerTransactionManager
    {
     static ThreadLocal> threadLocalDAOList = new ThreadLocal>();

     public static void Add(DataLayerSession dao) 
     {
        List list;

        list=threadLocalDAOList.get();

        if ( list == null )
        {
            list=new ArrayList();
            threadLocalDAOList.set(list);
        }

        list.add(dao);
        }

     public static void Remove(DataLayerSession dao) 
     {
        List list;

        list=threadLocalDAOList.get();

        if ( list == null )
            return;

        list.remove(dao);       
        }

        public static void RollBackTransactions()
        {
            List list;

            list=DataLayerTransactionManager.threadLocalDAOList.get();

            if ( DataLayerTransactionManager.threadLocalDAOList.get()==null)
                return;

            for (DataLayerSession session : list)
            {
             try
                {
                session.rollbackTransaction();

              Logger log;

                    log=LoggerFactory.getLogger(DataLayerTransactionManager.class);
                    log.error("Rollingback pending transaction "+session.toString() );
                } 
             catch (Exception e)
                {
                    Logger log;

                    log=LoggerFactory.getLogger(DataLayerTransactionManager.class);
                    log.error("",e);
                }                            
            }

            list.clear();

            DataLayerTransactionManager.threadLocalDAOList.set(null);
        }
    }


...