Мой бизнес-уровень реализован на 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);
}
}