java - Spring Rabbit 和 JDBC 事务问题

标签 java spring-data spring-amqp spring-rabbit

我有两个 Spring Rabbit 消费者 A 和 B。

消费者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());

}

消费者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);


}

看起来消费者 A 中的 jdbc 事务是在退出监听器方法后提交的,这就是可能发生重叠的原因。我的“ session ”条目有一个@Version 列,这就是我发现这个问题的原因。如何避免它?这是一个好方法吗?我只需要在消费者A中处理一个 session ,然后传递给消费者B即可。

最佳答案

我认为您可能在这里谈论 spring-data 而不是 spring-jdbc。如果是这种情况(抱歉,如果不是)并且您正在使用 CrudRepository,那么可能是因为与存储库的交互都是 @Transactional

例如,这里是 save 的实际签名

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

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

我建议重构以下内容并重试:-

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; 
}

@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);
}

这应该使交易单位匹配。尝试一下我就知道了。

关于java - Spring Rabbit 和 JDBC 事务问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40517987/

相关文章:

java - 在 Spring Data MongoDB 存储库中计数

java - 搜索没有主键的记录

java - Spring-Data JPA CrudRepository 返回 Iterable,可以将其转换为 List 吗?

java - 在 Struts 2 中处理 ActionForward

java - 默认接口(interface)方法如何调用其超对象的方法? (例如克隆)

java - 由 : java. lang.ClassNotFoundException 引起:在路径上找不到类 "android.support.v4.animation.AnimatorCompatHelper":DexPathList [[zip 文件

Java 程序仅适用于 Netbeans 中的断点

spring-amqp - Spring AMQP 错误处理程序和返回异常问题

Spring AMQP RPC 非默认交换

java - Spring amqp 拒绝监听器外部的消息