Spring 为什么Amazon sqs不支持事务?

Spring 为什么Amazon sqs不支持事务?,spring,amazon-web-services,rabbitmq,activemq,amazon-sqs,Spring,Amazon Web Services,Rabbitmq,Activemq,Amazon Sqs,在Spring中,Rabbitmq支持事务。但是,AmazonSQS不支持Spring中的事务 对不起。我又添加了一些内容。 我在spring中测试了两个消息队列(rabbitmq、AmazonSQS),如下所示 我的目的是在用户无一例外地完成注册时,将用户电子邮件处理到队列以发送注册完成电子邮件 //rabbit mq configuration.class @Bean public ConnectionFactory rabbitConnectionFactory() { Cachi

在Spring中,Rabbitmq支持事务。但是,AmazonSQS不支持Spring中的事务

对不起。我又添加了一些内容。 我在spring中测试了两个消息队列(rabbitmq、AmazonSQS),如下所示

我的目的是在用户无一例外地完成注册时,将用户电子邮件处理到队列以发送注册完成电子邮件

//rabbit mq configuration.class
@Bean
public ConnectionFactory rabbitConnectionFactory() {
    CachingConnectionFactory connectionFactory =
            new CachingConnectionFactory("localhost",5672);
    connectionFactory.setUsername("guest");
    connectionFactory.setPassword("guest");
    return connectionFactory;
}

@Bean
public SimpleMessageListenerContainer messageListenerContainer() {
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
    container.setConnectionFactory(rabbitConnectionFactory());
    container.setQueueNames(queue);
   container.setMessageListener(exampleListener());
    container.setTransactionManager(platformTransactionManager);
    container.setChannelTransacted(true);
    return container;
}


@Bean
public RabbitTemplate producerRabbitTemplate() {
    RabbitTemplate rabbitTemplate = new RabbitTemplate(rabbitConnectionFactory());
    rabbitTemplate.setQueue(queue);
    rabbitTemplate.setMandatory(true);
    rabbitTemplate.isChannelTransacted();
    rabbitTemplate.setChannelTransacted(true);
    return rabbitTemplate;
}



//UserService.class
@Autowired
private final UserRepository userRepository;
@Autowired
private final RabbitTemplate rabbitTemplate;

@Transactional
public User createUser(final User user){
    rabbitTemplate.convertAndSend("spring-boot", user.getEmail()); // SignUp Completion email
    final User user = userRepository.save(user);
    if(true) throw new RuntimeException();
    return user;
}
但是,上面的逻辑会发生runtimeException

如果发生异常,由于Spring中的事务性注释,Rabbit mq将不会向队列发送数据

//amazon sqs configuration.class
@Bean
public QueueMessagingTemplate queueMessagingTemplate(AmazonSQSAsync amazonSqs) {

//UserService.class
@Autowired
private final UserRepository userRepository;
@Autowired
private QueueMessagingTemplate messagingTemplate;


@Transactional
public User createUser(final User user){
    messagingTemplate.convertAndSend("spring-boot", user.getEmail()); // SignUp Completion email
    final User user = userRepository.save(user);
    if(true) throw new RuntimeException();
    return user;
}
但是,即使发生异常,sqs也将向队列发送数据

//amazon sqs configuration.class
@Bean
public QueueMessagingTemplate queueMessagingTemplate(AmazonSQSAsync amazonSqs) {

//UserService.class
@Autowired
private final UserRepository userRepository;
@Autowired
private QueueMessagingTemplate messagingTemplate;


@Transactional
public User createUser(final User user){
    messagingTemplate.convertAndSend("spring-boot", user.getEmail()); // SignUp Completion email
    final User user = userRepository.save(user);
    if(true) throw new RuntimeException();
    return user;
}

有人知道这是为什么吗?

TLDR如何解决这个问题?

不要试图为此使用事务,想出一些方法使系统最终保持一致。


听起来您想执行“queue.sendmages”和“repository.save”,就好像它们是一个事务一样-要么都得到提交,要么都没有得到提交。问题是“事务”不是真正的事务性的,即使在兔子的例子中也是如此

考虑事务工作原理的基本知识:

  • 某种类型的
    开始
    步骤,表示以下更改是事务的一部分
  • 进行了更改(但对读者不可见)
  • 某种类型的
    commit
    步骤以原子方式提交更改(使更改对读者可见)
  • 但是,在您的情况下,队列和存储库是独立的实体,由独立的网络资源支持,彼此不通信。在这种情况下没有原子提交。如果没有原子提交,就不能有真正的事务。它在您的演示中“起作用”,因为异常与编写代码是分开的

    考虑此案例以更清楚地说明:

    @Transactional
    public User createUser(final User user){
        messagingTemplate.convertAndSend("spring-boot", user.getEmail());
        final User user = userRepository.save(user);
        return user;
    }
    
    • 为此启动提交步骤时,它需要使消息(在队列中)和用户(在repo中)都可见
    • 为了做到这一点,需要对队列和repo进行网络调用
      • 这两个电话是问题的根源
    • 如果一个成功,而另一个失败,那么您将处于不一致的状态
      • 您可能会说“事务可以回滚”-但回滚将涉及另一个网络调用,这当然可能会失败

    有很多方法可以使整个分布式系统具有事务性,但这是一个复杂的问题。考虑到暂时的不一致性,并建立机制使系统最终保持一致,通常会更容易、更快。

    SQS实际上只是一个消息队列。你能举例说明你想解决什么问题,以及你认为“交易”会有什么帮助吗?从那里我们可以帮助你解决这个问题。@Krease你能检查上面的内容吗?