开启事务
注册Rabbit事务管理器,本质还是实现了Spring的PlatformTransactionManager
1 2 3 4 5 6
| @Bean public RabbitTransactionManager rabbitTransactionManager(CachingConnectionFactory connectionFactory, RabbitTemplate rabbitTemplate) { rabbitTemplate.setChannelTransacted(true); return new RabbitTransactionManager(connectionFactory); }
|
发送消息
1 2 3 4 5 6 7 8 9 10 11 12
| @Transactional public void send(String messageStr, String routeKey) { String messageId = String.valueOf(UUID.randomUUID()); Body body = new Body(); body.setCreateTime(DateTime.now()); body.setMessage(messageStr); body.setMessageId(messageId); rabbitTemplate.convertAndSend("testTopic", routeKey, body); System.out.println(rabbitTemplate.isChannelTransacted()); }
|
拦截器
我们知道spring声明式事务的核心就是aop拦截器,那么spring是如何拦截rabbit的呢
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, TransactionAspectSupport.InvocationCallback invocation) throws Throwable { TransactionAttributeSource tas = this.getTransactionAttributeSource(); TransactionAttribute txAttr = tas != null ? tas.getTransactionAttribute(method, targetClass) : null; PlatformTransactionManager tm = this.determineTransactionManager(txAttr); String joinpointIdentification = this.methodIdentification(method, targetClass, txAttr); Object result; if (txAttr != null && tm instanceof CallbackPreferringPlatformTransactionManager) { } else { TransactionAspectSupport.TransactionInfo txInfo = this.createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
try { result = invocation.proceedWithInvocation(); } catch (Throwable var17) { this.completeTransactionAfterThrowing(txInfo, var17); throw var17; } finally { this.cleanupTransactionInfo(txInfo); } this.commitTransactionAfterReturning(txInfo); return result; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| protected void completeTransactionAfterThrowing(@Nullable TransactionAspectSupport.TransactionInfo txInfo, Throwable ex) { if (txInfo != null && txInfo.getTransactionStatus() != null) { if (this.logger.isTraceEnabled()) { this.logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "] after exception: " + ex); } if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) { try { txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus()); } catch (TransactionSystemException var6) { this.logger.error("Application exception overridden by rollback exception", ex); var6.initApplicationException(ex); throw var6; } catch (Error | RuntimeException var7) { this.logger.error("Application exception overridden by rollback exception", ex); throw var7; } } else { try { txInfo.getTransactionManager().commit(txInfo.getTransactionStatus()); } catch (TransactionSystemException var4) { this.logger.error("Application exception overridden by commit exception", ex); var4.initApplicationException(ex); throw var4; } catch (Error | RuntimeException var5) { this.logger.error("Application exception overridden by commit exception", ex); throw var5; } } }
}
|
总结
rabbitmq本身的事务是通过channel.txSelect、channel.txCommit、channel.txRollback实现的,spring是在rabbitmq本身事务的基础上加了一层事务