spring transaction example

This commit is contained in:
Struchkov Mark 2022-07-24 07:52:04 +03:00
parent cbe943be85
commit 8e259a6a4e
14 changed files with 313 additions and 0 deletions

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-boot-transaction</artifactId>
<groupId>dev.struchkov.example</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-transaction</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.7.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>jakarta.persistence</groupId>-->
<!-- <artifactId>jakarta.persistence-api</artifactId>-->
<!-- <version>3.1.0</version>-->
<!-- </dependency>-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,11 @@
### Смотрим на первого пользователя
GET http://localhost:8080/api/person/1
Accept: application/json
### Смотрим на второго пользователя
GET http://localhost:8080/api/person/2
Accept: application/json
### Смотрим на третьего пользователя
GET http://localhost:8080/api/person/3
Accept: application/json

View File

@ -0,0 +1,9 @@
### Отправляем деньги от первого пользователя втором
POST http://localhost:8080/api/money/send
Content-Type: application/json
{
"personFrom": 1,
"personTo": 2,
"amount": 100
}

View File

@ -0,0 +1,13 @@
package dev.struchkov.example.transaction;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@ -0,0 +1,25 @@
package dev.struchkov.example.transaction.controller;
import dev.struchkov.example.transaction.domain.Person;
import dev.struchkov.example.transaction.repository.PersonRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Optional;
@RestController
@RequestMapping("/api/person")
@RequiredArgsConstructor
public class PersonController {
private final PersonRepository personRepository;
@GetMapping("{id}")
public Optional<Person> getById(@PathVariable Long id) {
return personRepository.findById(id);
}
}

View File

@ -0,0 +1,29 @@
package dev.struchkov.example.transaction.controller;
import dev.struchkov.example.transaction.dto.TransactionDto;
import dev.struchkov.example.transaction.service.TransactionMoneyService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("api/money")
@RequiredArgsConstructor
public class TransactionMoneyController {
private final TransactionMoneyService service;
@PostMapping("send")
public HttpStatus sendMoney(@RequestBody TransactionDto transactionDto) {
service.sendMoney(
transactionDto.getPersonFrom(),
transactionDto.getPersonTo(),
transactionDto.getAmount()
);
return HttpStatus.OK;
}
}

View File

@ -0,0 +1,29 @@
package dev.struchkov.example.transaction.domain;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Getter
@Setter
@Table(name = "person")
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "balance")
private Long balance;
}

View File

@ -0,0 +1,36 @@
package dev.struchkov.example.transaction.domain;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Getter
@Setter
@Table(name = "transaction")
public class TransactionMoney {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "person_from")
private Person personFrom;
@ManyToOne
@JoinColumn(name = "person_to")
private Person personTo;
@Column(name = "amount")
private Long amount;
}

View File

@ -0,0 +1,14 @@
package dev.struchkov.example.transaction.dto;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class TransactionDto {
private Long personFrom;
private Long personTo;
private Long amount;
}

View File

@ -0,0 +1,16 @@
package dev.struchkov.example.transaction.repository;
import dev.struchkov.example.transaction.domain.Person;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface PersonRepository extends JpaRepository<Person, Long> {
@Query(nativeQuery = true, value = "SELECT person.balance FROM person WHERE id = :id")
Long getBalance(@Param("id") Long id);
@Query("SELECT p.balance FROM Person p WHERE p.id = :id")
Long getBalanceJpql(@Param("id") Long id);
}

View File

@ -0,0 +1,7 @@
package dev.struchkov.example.transaction.repository;
import dev.struchkov.example.transaction.domain.TransactionMoney;
import org.springframework.data.jpa.repository.JpaRepository;
public interface TransactionMoneyRepository extends JpaRepository<TransactionMoney, Long> {
}

View File

@ -0,0 +1,38 @@
package dev.struchkov.example.transaction.service;
import dev.struchkov.example.transaction.domain.Person;
import dev.struchkov.example.transaction.domain.TransactionMoney;
import dev.struchkov.example.transaction.repository.PersonRepository;
import dev.struchkov.example.transaction.repository.TransactionMoneyRepository;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@RequiredArgsConstructor
public class TransactionMoneyService {
private final TransactionMoneyRepository transactionMoneyRepository;
private final PersonRepository personRepository;
@Transactional
public void sendMoney(@NonNull Long personFromId, @NonNull Long personToId, @NonNull Long amount) {
final Person personFrom = personRepository.findById(personFromId).orElseThrow();
final Person personTo = personRepository.findById(personToId).orElseThrow();
final TransactionMoney transactionMoney = new TransactionMoney();
transactionMoney.setPersonTo(personTo);
transactionMoney.setPersonFrom(personFrom);
transactionMoney.setAmount(amount);
transactionMoneyRepository.save(transactionMoney);
personFrom.setBalance(personFrom.getBalance() - amount);
personTo.setBalance(personTo.getBalance() + amount);
}
public void surprise() {
throw new RuntimeException("Сюрприиииз");
}
}

View File

@ -0,0 +1,15 @@
spring:
datasource:
password: 121314Ma
username: postgres
url: jdbc:postgresql://localhost:5432/test
driver-class-name: org.postgresql.Driver
jpa:
properties:
hibernate:
format_sql: true
logging:
level:
org.springframework.orm.jpa: DEBUG
org.springframework.transaction: DEBUG

View File

@ -0,0 +1,14 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="org.hibernate.SQL" level="DEBUG" />
<logger name="org.hibernate.type" level="TRACE" />
<root level="info">
<appender-ref ref="STDOUT"/>
</root>
</configuration>