From c3e77b712b50fe4a69b5b4b83243abf689cc34b0 Mon Sep 17 00:00:00 2001 From: stvort Date: Sat, 17 Jul 2021 01:58:18 +0400 Subject: [PATCH] readonly-transaction-demo example added --- examples/readonly-transaction-demo/pom.xml | 74 +++++++++++++++++++ .../ReadonlyTransactionDemoApplication.java | 13 ++++ .../main/java/ru/otus/demo/model/Person.java | 23 ++++++ .../demo/repository/PersonRepository.java | 13 ++++ .../demo/repository/PersonRepositoryJpa.java | 43 +++++++++++ .../ru/otus/demo/services/PersonService.java | 36 +++++++++ .../src/main/resources/application.yml | 19 +++++ .../src/main/resources/schema.sql | 7 ++ .../otus/demo/services/PersonServiceTest.java | 42 +++++++++++ 9 files changed, 270 insertions(+) create mode 100644 examples/readonly-transaction-demo/pom.xml create mode 100644 examples/readonly-transaction-demo/src/main/java/ru/otus/demo/ReadonlyTransactionDemoApplication.java create mode 100644 examples/readonly-transaction-demo/src/main/java/ru/otus/demo/model/Person.java create mode 100644 examples/readonly-transaction-demo/src/main/java/ru/otus/demo/repository/PersonRepository.java create mode 100644 examples/readonly-transaction-demo/src/main/java/ru/otus/demo/repository/PersonRepositoryJpa.java create mode 100644 examples/readonly-transaction-demo/src/main/java/ru/otus/demo/services/PersonService.java create mode 100644 examples/readonly-transaction-demo/src/main/resources/application.yml create mode 100644 examples/readonly-transaction-demo/src/main/resources/schema.sql create mode 100644 examples/readonly-transaction-demo/src/test/java/ru/otus/demo/services/PersonServiceTest.java diff --git a/examples/readonly-transaction-demo/pom.xml b/examples/readonly-transaction-demo/pom.xml new file mode 100644 index 00000000..71dc3930 --- /dev/null +++ b/examples/readonly-transaction-demo/pom.xml @@ -0,0 +1,74 @@ + + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 2.5.2 + + + + ru.otus + readonly-transaction-demo + 0.0.1-SNAPSHOT + readonly-transaction-demo + Readonly transaction demo + + + 11 + + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + + + com.h2database + h2 + runtime + + + + org.projectlombok + lombok + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/examples/readonly-transaction-demo/src/main/java/ru/otus/demo/ReadonlyTransactionDemoApplication.java b/examples/readonly-transaction-demo/src/main/java/ru/otus/demo/ReadonlyTransactionDemoApplication.java new file mode 100644 index 00000000..6220dc01 --- /dev/null +++ b/examples/readonly-transaction-demo/src/main/java/ru/otus/demo/ReadonlyTransactionDemoApplication.java @@ -0,0 +1,13 @@ +package ru.otus.demo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ReadonlyTransactionDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(ReadonlyTransactionDemoApplication.class, args); + } + +} diff --git a/examples/readonly-transaction-demo/src/main/java/ru/otus/demo/model/Person.java b/examples/readonly-transaction-demo/src/main/java/ru/otus/demo/model/Person.java new file mode 100644 index 00000000..95729249 --- /dev/null +++ b/examples/readonly-transaction-demo/src/main/java/ru/otus/demo/model/Person.java @@ -0,0 +1,23 @@ +package ru.otus.demo.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +public class Person { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + private String name; + +} diff --git a/examples/readonly-transaction-demo/src/main/java/ru/otus/demo/repository/PersonRepository.java b/examples/readonly-transaction-demo/src/main/java/ru/otus/demo/repository/PersonRepository.java new file mode 100644 index 00000000..c9ebdf9d --- /dev/null +++ b/examples/readonly-transaction-demo/src/main/java/ru/otus/demo/repository/PersonRepository.java @@ -0,0 +1,13 @@ +package ru.otus.demo.repository; + +import ru.otus.demo.model.Person; + +import java.util.List; + +public interface PersonRepository { + + Person save(Person person); + + List findAll(); + Person findById(long id); +} diff --git a/examples/readonly-transaction-demo/src/main/java/ru/otus/demo/repository/PersonRepositoryJpa.java b/examples/readonly-transaction-demo/src/main/java/ru/otus/demo/repository/PersonRepositoryJpa.java new file mode 100644 index 00000000..3e97d85d --- /dev/null +++ b/examples/readonly-transaction-demo/src/main/java/ru/otus/demo/repository/PersonRepositoryJpa.java @@ -0,0 +1,43 @@ +package ru.otus.demo.repository; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; +import ru.otus.demo.model.Person; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.TypedQuery; +import java.util.List; + +@Repository +@RequiredArgsConstructor +public class PersonRepositoryJpa implements PersonRepository { + + @PersistenceContext + private final EntityManager em; + + @Override + public Person save(Person person) { + if (person.getId() == 0) { + Person savedPerson = new Person(person.getId(), person.getName()); + em.persist(savedPerson); + return savedPerson; + + } + return em.merge(person); + } + + @Override + public List findAll() { + TypedQuery query = em.createQuery("select p from Person p", Person.class); + return query.getResultList(); + } + + @Override + public Person findById(long id) { + TypedQuery query = em.createQuery("select p from Person p where p.id = :id", Person.class); + query.setParameter("id", id); + return query.getSingleResult(); + + } +} diff --git a/examples/readonly-transaction-demo/src/main/java/ru/otus/demo/services/PersonService.java b/examples/readonly-transaction-demo/src/main/java/ru/otus/demo/services/PersonService.java new file mode 100644 index 00000000..cc672d1b --- /dev/null +++ b/examples/readonly-transaction-demo/src/main/java/ru/otus/demo/services/PersonService.java @@ -0,0 +1,36 @@ +package ru.otus.demo.services; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import ru.otus.demo.model.Person; +import ru.otus.demo.repository.PersonRepository; + +@Service +public class PersonService { + private final PersonRepository personRepository; + + public PersonService(PersonRepository personRepository) { + this.personRepository = personRepository; + } + + public Person findById(long id) { + return personRepository.findById(id); + } + + @Transactional + public void save(Person person){ + personRepository.save(person); + } + + @Transactional + public void updateWithNormalTran(long id, String name) { + Person person = personRepository.findById(id); + person.setName(name); + } + + @Transactional(readOnly = true) + public void updateWithReadonlyTran(long id, String name) { + Person person = personRepository.findById(id); + person.setName(name); + } +} diff --git a/examples/readonly-transaction-demo/src/main/resources/application.yml b/examples/readonly-transaction-demo/src/main/resources/application.yml new file mode 100644 index 00000000..9ddf5b1e --- /dev/null +++ b/examples/readonly-transaction-demo/src/main/resources/application.yml @@ -0,0 +1,19 @@ +spring: + datasource: + #url: jdbc:postgresql://localhost:5432/persons + #username: postgres + #password: postgres + + url: jdbc:h2:mem:testdb + + initialization-mode: always + + jpa: + generate-ddl: false + hibernate: + ddl-auto: none + + show-sql: true + properties: + hibernate: + #format_sql: true \ No newline at end of file diff --git a/examples/readonly-transaction-demo/src/main/resources/schema.sql b/examples/readonly-transaction-demo/src/main/resources/schema.sql new file mode 100644 index 00000000..0b626688 --- /dev/null +++ b/examples/readonly-transaction-demo/src/main/resources/schema.sql @@ -0,0 +1,7 @@ +drop table if exists person; + +create table person ( + id bigserial, + name varchar(200), + primary key(id) +); diff --git a/examples/readonly-transaction-demo/src/test/java/ru/otus/demo/services/PersonServiceTest.java b/examples/readonly-transaction-demo/src/test/java/ru/otus/demo/services/PersonServiceTest.java new file mode 100644 index 00000000..1814dc28 --- /dev/null +++ b/examples/readonly-transaction-demo/src/test/java/ru/otus/demo/services/PersonServiceTest.java @@ -0,0 +1,42 @@ +package ru.otus.demo.services; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import ru.otus.demo.model.Person; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +@SpringBootTest +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@Transactional(propagation = Propagation.NOT_SUPPORTED) +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +class PersonServiceTest { + + @Autowired + private PersonService personService; + + @BeforeEach + void setUp() { + personService.save(new Person(0, "Igor")); + } + + @Test + void updateWithNormalTran() { + personService.updateWithNormalTran(1, "Vasya"); + Person actualPerson = personService.findById(1); + assertThat(actualPerson).extracting(Person::getName).isEqualTo("Vasya"); + } + + @Test + void updateWithReadonlyTran() { + personService.updateWithReadonlyTran(1, "Vasya"); + Person actualPerson = personService.findById(1); + assertThat(actualPerson).extracting(Person::getName).isEqualTo("Igor"); + } +} \ No newline at end of file