Как предотвратить обновление БД вне транзакционного метода при включении spring-session-jdbc - PullRequest
1 голос
/ 29 апреля 2020

У меня проблема с поведением того, как работает весенняя транзакция. Мне не ясно, как правильно это реализовать. Эта проблема возникает, только если я включаю зависимость spring-session-jdbc.

  • Я использую Spring Boot 2.2.6
  • с Hibernate / Mariadb
  • Spring security включен с InMemoryUserDetailsManager

У меня есть метод, который аннотируется как @Transactional(readonly=true) и возвращает коллекцию сущностей. После получения коллекции от этого метода перед отправкой я установил для некоторых переменных разные значения, чтобы они не отображались или не меняли представление. Проблема в том, что после отправки вывода значения базы данных автоматически обновляются .

Чтобы подвести итог, я создал базовый проект c SpringBoot 2.2.6, ниже приводится его содержание.

Заказчик. java

@Data
@Entity
@Table(name = "customers")
public class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private Integer age;
    private Integer batch;
    private String secret;

}

CustomerRepository. java

@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {

    Page<Customer> findByBatch(Integer batchId, Pageable pagaable);
}

CustomerService. java Следует отметить, что в этом классе обслуживания метод аннотирован с @Transactional(readOnly = true).

@Service
public class CustomerService {

    @Autowired
    private CustomerRepository repo;

    @Transactional(readOnly = true)
    public Page<Customer> findAllCustomers() {

        Pageable pageable = PageRequest.of(0, 10);

        return repo.findByBatch(4, pageable);
    }
}

CustController. java

@Controller
public class CustController {

    @Autowired
    private CustomerService service;

    @GetMapping("/")
    public ResponseEntity<Page<Customer>> indexPath(Model model) {

        Page<Customer> customers = this.service.findAllCustomers();

        model.addAttribute("customers", customers);
        // setting null before sending to client
        // this is for demonstration purpose only
        customers.getContent().forEach(i -> i.setSecret(null));

        return ResponseEntity.ok(customers);
    }
}

Зависимости в пом. xml

  • spring-boot-starter-data-jpa
  • spring-boot-starter-thymeleaf
  • spring-boot-starter-web
  • spring-boot -starter-security
  • mariadb- java -клиент
  • ломбок
  • spring-session-jdb c

и заполнять база данных ниже содержит несколько SQL операторов вставки.

CREATE TABLE IF NOT EXISTS `customers` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `age` int(11) DEFAULT NULL,
  `batch` int(11) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  `secret` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM; // changed to InnoDB basedon @M.Deinum comment

INSERT INTO `customers` (`id`, `age`, `batch`, `name`, `secret`) VALUES (1, 94, 4, 'Ravi', '23423424234');
INSERT INTO `customers` (`id`, `age`, `batch`, `name`, `secret`) VALUES (2, 32, 4, 'Silva', '3424252432');
INSERT INTO `customers` (`id`, `age`, `batch`, `name`, `secret`) VALUES (3, 18, 4, 'Rahul', '322342424');

Пример проекта в Github

Я создал этот простой проект, который воспроизводит проблему, и загрузил это в Github в этом URL https://github.com/imuneer/sprintboot-db-issue.

* 10 72 * Просто закомментировав spring-session-jdbc в пом. xml, вы заставите проект работать как положено; никакое значение, которое я обновляю в моем контроллере, не изменяет фактические значения базы данных. Но когда spring-session-jdbc не прокомментирован, он работает наоборот.

Я запутался здесь.

  1. Почему добавление spring-session-jdbc меняет поведение весенней транзакции
  2. Я что-то пропустил, так что программа ведет себя по-разному в обоих сценариях ios?
  3. Или мое понимание неверно? Если да, то как правильно отсоединить коллекцию от контекста сохранности перед ее изменением на клиенте.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...