1 16 17 package org.springframework.jca.cci.connection; 18 19 import javax.resource.NotSupportedException ; 20 import javax.resource.ResourceException ; 21 import javax.resource.cci.Connection ; 22 import javax.resource.cci.ConnectionFactory ; 23 import javax.resource.spi.LocalTransactionException ; 24 25 import org.springframework.beans.factory.InitializingBean; 26 import org.springframework.transaction.CannotCreateTransactionException; 27 import org.springframework.transaction.TransactionDefinition; 28 import org.springframework.transaction.TransactionException; 29 import org.springframework.transaction.TransactionSystemException; 30 import org.springframework.transaction.support.AbstractPlatformTransactionManager; 31 import org.springframework.transaction.support.DefaultTransactionStatus; 32 import org.springframework.transaction.support.TransactionSynchronizationManager; 33 import org.springframework.transaction.support.ResourceTransactionManager; 34 35 63 public class CciLocalTransactionManager extends AbstractPlatformTransactionManager 64 implements ResourceTransactionManager, InitializingBean { 65 66 private ConnectionFactory connectionFactory; 67 68 69 74 public CciLocalTransactionManager() { 75 } 76 77 81 public CciLocalTransactionManager(ConnectionFactory connectionFactory) { 82 setConnectionFactory(connectionFactory); 83 afterPropertiesSet(); 84 } 85 86 87 91 public void setConnectionFactory(ConnectionFactory cf) { 92 if (cf instanceof TransactionAwareConnectionFactoryProxy) { 93 this.connectionFactory = ((TransactionAwareConnectionFactoryProxy) cf).getTargetConnectionFactory(); 97 } 98 else { 99 this.connectionFactory = cf; 100 } 101 } 102 103 107 public ConnectionFactory getConnectionFactory() { 108 return this.connectionFactory; 109 } 110 111 public void afterPropertiesSet() { 112 if (getConnectionFactory() == null) { 113 throw new IllegalArgumentException ("Property 'connectionFactory' is required"); 114 } 115 } 116 117 118 public Object getResourceFactory() { 119 return getConnectionFactory(); 120 } 121 122 protected Object doGetTransaction() { 123 CciLocalTransactionObject txObject = new CciLocalTransactionObject(); 124 ConnectionHolder conHolder = 125 (ConnectionHolder) TransactionSynchronizationManager.getResource(getConnectionFactory()); 126 txObject.setConnectionHolder(conHolder); 127 return txObject; 128 } 129 130 protected boolean isExistingTransaction(Object transaction) { 131 CciLocalTransactionObject txObject = (CciLocalTransactionObject) transaction; 132 return (txObject.getConnectionHolder() != null); 134 } 135 136 protected void doBegin(Object transaction, TransactionDefinition definition) { 137 CciLocalTransactionObject txObject = (CciLocalTransactionObject) transaction; 138 139 Connection con = null; 140 141 try { 142 con = getConnectionFactory().getConnection(); 143 if (logger.isDebugEnabled()) { 144 logger.debug("Acquired Connection [" + con + "] for local CCI transaction"); 145 } 146 147 txObject.setConnectionHolder(new ConnectionHolder(con)); 148 txObject.getConnectionHolder().setSynchronizedWithTransaction(true); 149 150 con.getLocalTransaction().begin(); 151 int timeout = determineTimeout(definition); 152 if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) { 153 txObject.getConnectionHolder().setTimeoutInSeconds(timeout); 154 } 155 TransactionSynchronizationManager.bindResource(getConnectionFactory(), txObject.getConnectionHolder()); 156 } 157 158 catch (NotSupportedException ex) { 159 ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory()); 160 throw new CannotCreateTransactionException("CCI Connection does not support local transactions", ex); 161 } 162 catch (LocalTransactionException ex) { 163 ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory()); 164 throw new CannotCreateTransactionException("Could not begin local CCI transaction", ex); 165 } 166 catch (ResourceException ex) { 167 ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory()); 168 throw new TransactionSystemException("Unexpected failure on begin of CCI local transaction", ex); 169 } 170 } 171 172 protected Object doSuspend(Object transaction) { 173 CciLocalTransactionObject txObject = (CciLocalTransactionObject) transaction; 174 txObject.setConnectionHolder(null); 175 return TransactionSynchronizationManager.unbindResource(getConnectionFactory()); 176 } 177 178 protected void doResume(Object transaction, Object suspendedResources) { 179 ConnectionHolder conHolder = (ConnectionHolder) suspendedResources; 180 TransactionSynchronizationManager.bindResource(getConnectionFactory(), conHolder); 181 } 182 183 protected boolean isRollbackOnly(Object transaction) throws TransactionException { 184 CciLocalTransactionObject txObject = (CciLocalTransactionObject) transaction; 185 return txObject.getConnectionHolder().isRollbackOnly(); 186 } 187 188 protected void doCommit(DefaultTransactionStatus status) { 189 CciLocalTransactionObject txObject = (CciLocalTransactionObject) status.getTransaction(); 190 Connection con = txObject.getConnectionHolder().getConnection(); 191 if (status.isDebug()) { 192 logger.debug("Committing CCI local transaction on Connection [" + con + "]"); 193 } 194 try { 195 con.getLocalTransaction().commit(); 196 } 197 catch (LocalTransactionException ex) { 198 throw new TransactionSystemException("Could not commit CCI local transaction", ex); 199 } 200 catch (ResourceException ex) { 201 throw new TransactionSystemException("Unexpected failure on commit of CCI local transaction", ex); 202 } 203 } 204 205 protected void doRollback(DefaultTransactionStatus status) { 206 CciLocalTransactionObject txObject = (CciLocalTransactionObject) status.getTransaction(); 207 Connection con = txObject.getConnectionHolder().getConnection(); 208 if (status.isDebug()) { 209 logger.debug("Rolling back CCI local transaction on Connection [" + con + "]"); 210 } 211 try { 212 con.getLocalTransaction().rollback(); 213 } 214 catch (LocalTransactionException ex) { 215 throw new TransactionSystemException("Could not roll back CCI local transaction", ex); 216 } 217 catch (ResourceException ex) { 218 throw new TransactionSystemException("Unexpected failure on rollback of CCI local transaction", ex); 219 } 220 } 221 222 protected void doSetRollbackOnly(DefaultTransactionStatus status) { 223 CciLocalTransactionObject txObject = (CciLocalTransactionObject) status.getTransaction(); 224 if (status.isDebug()) { 225 logger.debug("Setting CCI local transaction [" + txObject.getConnectionHolder().getConnection() + 226 "] rollback-only"); 227 } 228 txObject.getConnectionHolder().setRollbackOnly(); 229 } 230 231 protected void doCleanupAfterCompletion(Object transaction) { 232 CciLocalTransactionObject txObject = (CciLocalTransactionObject) transaction; 233 234 TransactionSynchronizationManager.unbindResource(getConnectionFactory()); 236 txObject.getConnectionHolder().clear(); 237 238 Connection con = txObject.getConnectionHolder().getConnection(); 239 if (logger.isDebugEnabled()) { 240 logger.debug("Releasing CCI Connection [" + con + "] after transaction"); 241 } 242 ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory()); 243 } 244 245 246 251 private static class CciLocalTransactionObject { 252 253 private ConnectionHolder connectionHolder; 254 255 public void setConnectionHolder(ConnectionHolder connectionHolder) { 256 this.connectionHolder = connectionHolder; 257 } 258 259 public ConnectionHolder getConnectionHolder() { 260 return connectionHolder; 261 } 262 } 263 264 } 265 | Popular Tags |