mirror of
https://github.com/Example-uPagge/transactional.git
synced 2024-06-14 11:52:55 +03:00
spring transaction example
This commit is contained in:
parent
cbe943be85
commit
8e259a6a4e
57
spring-transaction/pom.xml
Normal file
57
spring-transaction/pom.xml
Normal 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>
|
11
spring-transaction/rest/person-requests.http
Normal file
11
spring-transaction/rest/person-requests.http
Normal 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
|
9
spring-transaction/rest/transaction-money-requests.http
Normal file
9
spring-transaction/rest/transaction-money-requests.http
Normal file
@ -0,0 +1,9 @@
|
||||
### Отправляем деньги от первого пользователя втором
|
||||
POST http://localhost:8080/api/money/send
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"personFrom": 1,
|
||||
"personTo": 2,
|
||||
"amount": 100
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
@ -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> {
|
||||
}
|
@ -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("Сюрприиииз");
|
||||
}
|
||||
|
||||
}
|
15
spring-transaction/src/main/resources/application.yml
Normal file
15
spring-transaction/src/main/resources/application.yml
Normal 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
|
14
spring-transaction/src/main/resources/logback.xml
Normal file
14
spring-transaction/src/main/resources/logback.xml
Normal 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>
|
Loading…
Reference in New Issue
Block a user