001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.geronimo.connector.outbound; 019 020 import javax.resource.ResourceException; 021 import javax.transaction.RollbackException; 022 import javax.transaction.SystemException; 023 import javax.transaction.Transaction; 024 import javax.transaction.TransactionManager; 025 import javax.transaction.xa.XAResource; 026 027 /** 028 * TransactionEnlistingInterceptor.java 029 * <p/> 030 * <p/> 031 * Created: Fri Sep 26 14:52:24 2003 032 * 033 * @version 1.0 034 */ 035 public class TransactionEnlistingInterceptor implements ConnectionInterceptor { 036 037 private final ConnectionInterceptor next; 038 private final TransactionManager transactionManager; 039 040 public TransactionEnlistingInterceptor(ConnectionInterceptor next, TransactionManager transactionManager) { 041 this.next = next; 042 this.transactionManager = transactionManager; 043 } 044 045 public void getConnection(ConnectionInfo connectionInfo) throws ResourceException { 046 next.getConnection(connectionInfo); 047 try { 048 ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo(); 049 050 // get the current transation and status... if there is a problem just assume there is no transaction present 051 Transaction transaction = TxUtil.getTransactionIfActive(transactionManager); 052 if (transaction != null) { 053 XAResource xares = mci.getXAResource(); 054 transaction.enlistResource(xares); 055 } 056 } catch (SystemException e) { 057 returnConnection(connectionInfo, ConnectionReturnAction.DESTROY); 058 throw new ResourceException("Could not get transaction", e); 059 } catch (RollbackException e) { 060 //transaction is marked rolled back, so the xaresource could not have been enlisted 061 next.returnConnection(connectionInfo, ConnectionReturnAction.RETURN_HANDLE); 062 throw new ResourceException("Could not enlist resource in rolled back transaction", e); 063 } catch (Throwable t) { 064 returnConnection(connectionInfo, ConnectionReturnAction.DESTROY); 065 throw new ResourceException("Unknown throwable when trying to enlist connection in tx", t); 066 } 067 } 068 069 /** 070 * The <code>returnConnection</code> method 071 * <p/> 072 * todo Probably the logic needs improvement if a connection 073 * error occurred and we are destroying the handle. 074 * 075 * @param connectionInfo a <code>ConnectionInfo</code> value 076 * @param connectionReturnAction a <code>ConnectionReturnAction</code> value 077 */ 078 public void returnConnection(ConnectionInfo connectionInfo, 079 ConnectionReturnAction connectionReturnAction) { 080 try { 081 ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo(); 082 Transaction transaction = TxUtil.getTransactionIfActive(transactionManager); 083 if (transaction != null) { 084 XAResource xares = mci.getXAResource(); 085 transaction.delistResource(xares, XAResource.TMSUSPEND); 086 } 087 088 } catch (SystemException e) { 089 //maybe we should warn??? 090 connectionReturnAction = ConnectionReturnAction.DESTROY; 091 } catch (IllegalStateException e) { 092 connectionReturnAction = ConnectionReturnAction.DESTROY; 093 } 094 095 next.returnConnection(connectionInfo, connectionReturnAction); 096 } 097 098 public void destroy() { 099 next.destroy(); 100 } 101 102 }