简体   繁体   English

Spring Rabbit和JDBC事务问题

[英]Spring rabbit and JDBC transaction issue

I have two spring rabbit consumers A and B. 我有两个春季兔子消费者A和B。

consumer A: 消费者A:

protected void process(Message amqpMessage, Channel channel)
            throws Exception {
   Session mysession=sessionRepository.findOne(5);
   mysession.setMyField("bla");
   sessionRepository.save(mysession);
   ServicesHelper.convertAndSend(<Consumer B token>, mysession.getId());

}

Consumer B: 消费者B:

protected void process(Message amqpMessage, Channel channel)
            throws Exception {
   //getting event from message
   Long sessionId=5;
   Session mysession=sessionRepository.findOne(sessionId);
   mysession.setMyField("bla-bla");
   //And I get there unpredictable optimistic locking exception. 
   sessionRepository.save(mysession);


}

It seems like jdbc transaction in consumer A is being committed after exit from listener method, that's why overlapping is possible. 似乎在消费者A中的jdbc事务在从侦听器方法退出后正在提交,这就是为什么可以重叠的原因。 My 'session' entiry has a @Version column, that;s why I discovered this issue. 我的“会话”条目具有@Version列,这就是为什么我发现此问题的原因。 How to avoid it and is it good approach to do this? 如何避免这种情况,这是否是一个好方法? I just need to process a session in consumer A and then pass to consumer B. 我只需要在消费者A中处理一个会话,然后传递给消费者B。

I think you may be talking about spring-data here not spring-jdbc . 我认为您可能在这里谈论的是spring-data而不是spring-jdbc If this is the case ( apologies if it's not ) and you are using CrudRepository then it's probably because interactions with the repository are all @Transactional . 如果是这种情况(如果不是,则表示歉意),并且您正在使用CrudRepository则可能是因为与存储库的交互都是@Transactional

For example, here is the actual signature of save 例如,这是保存的实际签名

@Transactional
    public <S extends T> S save(S entity) {

        if (entityInformation.isNew(entity)) {
            em.persist(entity);
            return entity;
        } else {
            return em.merge(entity);
        }
    }

I would suggest refactoring to the following and trying again :- 我建议将其重构为以下内容,然后重试:-

protected void process(Message amqpMessage, Channel channel)
            throws Exception {

   ServicesHelper.convertAndSend(<Consumer B token>,adaptSession().getId()));

}

@Transactional
protected Session adaptSession(){
   Session mysession=sessionRepository.findOne(5);
   mysession.setMyField("bla");
   sessionRepository.save(mysession);
   return mysession; 
}

and

@Transactional
protected void process(Message amqpMessage, Channel channel)
            throws Exception {
   //getting event from message
   Long sessionId=5;
   Session mysession=sessionRepository.findOne(sessionId);
   mysession.setMyField("bla-bla");
   //And I get there unpredictable optimistic locking exception. 
   sessionRepository.save(mysession);
}

Which should make the transactional units match up. 哪个应该使交易单元匹配。 Try that and me know. 试试看,我知道。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM