๐Ÿ”„ ๋‚™๊ด€์  ๋ฝ(Optimistic Locking): ์„ฑ๋Šฅ๊ณผ ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ์„ ๋ชจ๋‘ ์žก๋‹ค! ๐Ÿš€

์„ํ˜„ยท2025๋…„ 1์›” 27์ผ
0

Insight

๋ชฉ๋ก ๋ณด๊ธฐ
8/43

์˜ค๋Š˜์˜ ์ด์•ผ๊ธฐ

์•ž์„œ ๋ฐ๋“œ๋ฝ ๊ด€๋ จ ๋ธ”๋กœ๊ทธ ๊ธ€์„ ์ž‘์„ฑํ•˜๋Š” ๊ณผ์ •์—์„œ ๋‚™๊ด€์  ๋ฝ(Optimistic Locking)์ด๋ผ๋Š” ๊ฐœ๋…๋„ ๊ฐ™์ด ์ •๋ฆฌํ•ด๋ณด๋ฉด ์ข‹์„๊ฒƒ ๊ฐ™์•„ ์ž‘์„ฑํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.๋‚™๊ด€์  ๋ฝ์€ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•˜๋ฉด์„œ๋„ ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ์„ ์œ ์ง€ํ•˜๋Š” ๋ฐ ํƒ์›”ํ•œ ๋„๊ตฌ์ธ๋ฐ์š”. ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ๋‚™๊ด€์  ๋ฝ์˜ ๊ฐœ๋…, ํ™œ์šฉ ์‚ฌ๋ก€, ๊ทธ๋ฆฌ๊ณ  ์‹ค์ œ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•๊นŒ์ง€ ์ •๋ฆฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


๋‚™๊ด€์  ๋ฝ์ด๋ž€? ๐Ÿค”

๋‚™๊ด€์  ๋ฝ์€ ๋™์‹œ์„ฑ ์ œ์–ด๋ฅผ ์œ„ํ•œ ๋ฉ”์ปค๋‹ˆ์ฆ˜ ์ค‘ ํ•˜๋‚˜๋กœ, ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐฑ์‹ ํ•˜๋Š” ๋™์•ˆ ์ถฉ๋Œ์ด ๋“œ๋ฌผ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ์„ค๊ณ„๋œ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ๋‚œ ํ›„ ๊ฐฑ์‹  ์‹œ์ ์— ์ถฉ๋Œ ์—ฌ๋ถ€๋ฅผ ๊ฒ€์‚ฌํ•˜๋ฉฐ, ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜๋ฉด ๋ณ€๊ฒฝ์„ ๊ฑฐ๋ถ€ํ•˜๊ฑฐ๋‚˜ ์žฌ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.

๋‚™๊ด€์  ๋ฝ์˜ ํ•ต์‹ฌ ์›๋ฆฌ

  • ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์„ ๋•Œ๋Š” ๋ณ„๋„์˜ ๋ฝ์„ ๊ฑธ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธํ•  ๋•Œ, ๋ฒ„์ „(Version) ์ •๋ณด๋‚˜ ํƒ€์ž„์Šคํƒฌํ”„(Timestamp)๋ฅผ ์ด์šฉํ•ด ๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • ๋งŒ์•ฝ ๋ฐ์ดํ„ฐ๊ฐ€ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์— ์˜ํ•ด ๋ณ€๊ฒฝ๋œ ๊ฒฝ์šฐ, ๊ฐฑ์‹ ์„ ๊ฑฐ๋ถ€ํ•˜๊ฑฐ๋‚˜ ์žฌ์‹œ๋„๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

๋น„๊ต: ๋น„๊ด€์  ๋ฝ(Pessimistic Locking)์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์„ ๋•Œ ๋ฝ์„ ๊ฑธ์–ด ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์˜ ์ ‘๊ทผ์„ ์ฐจ๋‹จํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.


๋‚™๊ด€์  ๋ฝ์ด ์œ ์šฉํ•œ ๊ฒฝ์šฐ ๐Ÿ“ˆ

๋‚™๊ด€์  ๋ฝ์€ ์ฝ๊ธฐ ์ž‘์—…์ด ๋งŽ๊ณ  ์“ฐ๊ธฐ ์ž‘์—…์ด ์ƒ๋Œ€์ ์œผ๋กœ ์ ์€ ํ™˜๊ฒฝ์—์„œ ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด:

  • SNS ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜: ์‚ฌ์šฉ์ž ํ”ผ๋“œ๋ฅผ ์ฝ๋Š” ์š”์ฒญ์ด ๋งŽ๊ณ , ์—…๋ฐ์ดํŠธ๋Š” ์ ์Œ.
  • ์ „์ž ์ƒ๊ฑฐ๋ž˜ ํ”Œ๋žซํผ: ์ œํ’ˆ ์ •๋ณด๋ฅผ ์กฐํšŒํ•˜๋Š” ๋นˆ๋„๊ฐ€ ๋†’์€ ๋ฐ˜๋ฉด, ์žฌ๊ณ  ์—…๋ฐ์ดํŠธ๋Š” ๋“œ๋ญ…๋‹ˆ๋‹ค.
  • ์˜ˆ์•ฝ ์‹œ์Šคํ…œ: ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ์ž๊ฐ€ ์กฐํšŒ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ, ์‹ค์ œ ์˜ˆ์•ฝ์€ ์ƒ๋Œ€์ ์œผ๋กœ ์ ์Œ.

๋‚™๊ด€์  ๋ฝ ๊ตฌํ˜„ ๋ฐฉ๋ฒ• ๐Ÿ› ๏ธ

1. ๋ฐ์ดํ„ฐ ๋ชจ๋ธ ์„ค๊ณ„

๋‚™๊ด€์  ๋ฝ์„ ๊ตฌํ˜„ํ•˜๋ ค๋ฉด ํ…Œ์ด๋ธ”์— ๋ฒ„์ „(Version) ํ•„๋“œ๋‚˜ ํƒ€์ž„์Šคํƒฌํ”„ ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

CREATE TABLE products (
    id BIGINT PRIMARY KEY,
    name VARCHAR(255),
    stock INT,
    version INT
);

2. ์—…๋ฐ์ดํŠธ ์ฟผ๋ฆฌ ์ž‘์„ฑ

์—…๋ฐ์ดํŠธ ์‹œ ํ˜„์žฌ ๋ฒ„์ „์„ ๊ธฐ์ค€์œผ๋กœ ์กฐ๊ฑด์„ ๊ฑธ์–ด ์ถฉ๋Œ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

UPDATE products
SET stock = stock - 1,
    version = version + 1
WHERE id = 1 AND version = 5;
  • ์ด ์ฟผ๋ฆฌ๋Š” id๊ฐ€ 1์ธ ์ƒํ’ˆ์˜ ๋ฒ„์ „์ด 5์ผ ๋•Œ๋งŒ ์—…๋ฐ์ดํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • ์กฐ๊ฑด์ด ๋งŒ์กฑ๋˜์ง€ ์•Š์œผ๋ฉด ์—…๋ฐ์ดํŠธ ์‹คํŒจ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

3. Java ๊ตฌํ˜„ ์˜ˆ์ œ

Spring Data JPA์™€ ํ•จ๊ป˜ ๋‚™๊ด€์  ๋ฝ์„ ์ ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

์—”ํ‹ฐํ‹ฐ ํด๋ž˜์Šค ์„ค์ •

import jakarta.persistence.*;

@Entity
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private Integer stock;

    @Version
    private Integer version;

    // Getter์™€ Setter ์ƒ๋žต
}

์„œ๋น„์Šค ๋ ˆ์ด์–ด ๊ตฌํ˜„

@Service
public class ProductService {

    @Autowired
    private ProductRepository productRepository;

    @Transactional
    public void updateStock(Long productId, int quantity) {
        Product product = productRepository.findById(productId)
            .orElseThrow(() -> new RuntimeException("Product not found"));

        if (product.getStock() < quantity) {
            throw new RuntimeException("Not enough stock");
        }

        product.setStock(product.getStock() - quantity);
        productRepository.save(product);
    }
}

@Version ์• ๋„ˆํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด JPA๊ฐ€ ์ž๋™์œผ๋กœ ๋ฒ„์ „์„ ๊ด€๋ฆฌํ•˜๋ฉฐ ์ถฉ๋Œ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.


๋‚™๊ด€์  ๋ฝ์˜ ์žฅ๋‹จ์  โš–๏ธ

์žฅ์ 

  • ๋†’์€ ์„ฑ๋Šฅ: ์ฝ๊ธฐ ์ž‘์—…์— ๋ฝ์„ ๊ฑธ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋น„๊ด€์  ๋ฝ๋ณด๋‹ค ์„ฑ๋Šฅ์ด ๋›ฐ์–ด๋‚จ.
  • ๊ฐ„๋‹จํ•œ ๊ตฌํ˜„: ๋ฒ„์ „ ํ•„๋“œ๋งŒ ์ถ”๊ฐ€ํ•˜๋ฉด ์‰ฝ๊ฒŒ ์ ์šฉ ๊ฐ€๋Šฅ.
  • ๋ฐ๋“œ๋ฝ ๋ฐฉ์ง€: ๋ฝ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋ฐ๋“œ๋ฝ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ.

๋‹จ์ 

  • ์ถฉ๋Œ ์ฒ˜๋ฆฌ ํ•„์š”: ์“ฐ๊ธฐ ์ž‘์—…์ด ๋งŽ๊ฑฐ๋‚˜ ์ถฉ๋Œ์ด ๋นˆ๋ฒˆํ•œ ํ™˜๊ฒฝ์—์„œ๋Š” ์‹คํŒจ์œจ์ด ๋†’์•„์งˆ ์ˆ˜ ์žˆ์Œ.
  • ์žฌ์‹œ๋„ ๋น„์šฉ: ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜๋ฉด ๊ฐฑ์‹ ์„ ์žฌ์‹œ๋„ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์ถ”๊ฐ€ ๋น„์šฉ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ.

๋‚™๊ด€์  ๋ฝ vs ๋น„๊ด€์  ๋ฝ ๐ŸฅŠ

๋‚™๊ด€์  ๋ฝ๋น„๊ด€์  ๋ฝ
๋ฝ ๋ฐฉ์‹๋ฒ„์ „ ํ•„๋“œ๋กœ ์ถฉ๋Œ ๊ฐ์ง€๋ฐ์ดํ„ฐ ์ฝ์„ ๋•Œ ๋ฝ ์„ค์ •
์„ฑ๋Šฅ์ฝ๊ธฐ ์ž‘์—…์ด ๋งŽ์€ ๊ฒฝ์šฐ ์œ ๋ฆฌ์“ฐ๊ธฐ ์ž‘์—…์ด ๋งŽ์€ ๊ฒฝ์šฐ ์œ ๋ฆฌ
๋ฐ๋“œ๋ฝ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ๋ฐœ์ƒ ๊ฐ€๋Šฅ
์ถฉ๋Œ ์ฒ˜๋ฆฌ์ถฉ๋Œ ์‹œ ๊ฐฑ์‹  ์‹คํŒจ ์ฒ˜๋ฆฌ ํ•„์š”์ถฉ๋Œ ๊ฐ€๋Šฅ์„ฑ์ด ์ ์Œ

๋งˆ์น˜๋ฉฐ ๐ŸŒŸ

๋‚™๊ด€์  ๋ฝ์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋™์‹œ์„ฑ ์ œ์–ด์—์„œ ๋งค์šฐ ์œ ์šฉํ•œ ๋„๊ตฌ๋กœ, ์„ฑ๋Šฅ๊ณผ ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ์˜ ๊ท ํ˜•์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ์ฝ๊ธฐ ์ž‘์—…์ด ๋งŽ์€ ํ™˜๊ฒฝ์—์„œ ํšจ๊ณผ์ ์ด๋ฉฐ, ๊ตฌํ˜„์ด ๊ฐ„๋‹จํ•˜๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์“ฐ๊ธฐ ์ž‘์—…์ด ๋งŽ๊ฑฐ๋‚˜ ์ถฉ๋Œ์ด ๋นˆ๋ฒˆํ•œ ํ™˜๊ฒฝ์—์„œ๋Š” ๋น„๊ด€์  ๋ฝ๊ณผ ๋น„๊ตํ•˜์—ฌ ์‹ ์ค‘ํžˆ ์„ ํƒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ๋ถ„๋„ ํ”„๋กœ์ ํŠธ์— ๋‚™๊ด€์  ๋ฝ์„ ๋„์ž…ํ•ด ํšจ์œจ์ ์ด๊ณ  ์•ˆ์ •์ ์ธ ๋™์‹œ์„ฑ ๊ด€๋ฆฌ๋ฅผ ๊ฒฝํ—˜ํ•ด๋ณด์„ธ์š”! ๐Ÿš€

0๊ฐœ์˜ ๋Œ“๊ธ€