[英]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.