๋™์‹œ์„ฑ ์ „๋žต

Hibernate์—์„œ 2์ฐจ ์บ์‹ฑ์„ ํ™œ์„ฑํ™”ํ•œ ํ›„์—๋Š” Hibernate์— ์–ด๋–ค Entity ๊ฐœ์ฒด๋ฅผ ์–ด๋–ป๊ฒŒ ์บ์‹ฑํ• ์ง€ ์„ค๋ช…ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ฅผ ์œ„ํ•ด Hibernate๋Š” Entity ํด๋ž˜์Šค์— ๋Œ€ํ•œ ํŠน๋ณ„ํ•œ ์ฃผ์„ - @Cache๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค . ์˜ˆ:

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

์ด ์ฃผ์„์€ ๋‘ ๋ฒˆ์งธ ์ˆ˜์ค€ ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๊ฐ ์—”ํ„ฐํ‹ฐ ์—”ํ„ฐํ‹ฐ์— ๋Œ€ํ•ด ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ:

@Entity
@Table(name = "employee")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Employee {
    @Id
    private Integer id;
    private Set<Task> tasks;
}

Hibernate๋Š” ์บ์‹œ๋œ ์—”ํ„ฐํ‹ฐ๊ฐ€ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ์•ก์„ธ์Šค๋˜๋Š” ๊ฒฝ์šฐ 4๊ฐ€์ง€ ๊ฐ€๋Šฅํ•œ ์•ก์„ธ์Šค ์ „๋žต์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ฝ๊ธฐ ์ „์šฉ
  • ์ฝ๊ธฐ-์“ฐ๊ธฐ
  • ์—„๊ฒฉํ•˜์ง€ ์•Š์€ ์ฝ๊ธฐ-์“ฐ๊ธฐ
  • ํŠธ๋žœ์žญ์…˜

์ฝ๊ธฐ ์ „์šฉ. ์ ˆ๋Œ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ์— ์ ํ•ฉํ•œ ๋™์‹œ์„ฑ ์ „๋žต. Hibernate๋Š” ๋‹จ์ˆœํžˆ ์ด๋Ÿฌํ•œ ๊ฐ์ฒด๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์ฐธ์กฐ ๋ฐ์ดํ„ฐ๋กœ๋งŒ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ์ ˆ๋Œ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ๋งŽ์€ ์ •๋ณด๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํ…Œ์ด๋ธ”์€ ์ถ”๊ฐ€๋˜๊ธฐ๋งŒ ํ•˜๊ณ  ๋ณ€๊ฒฝ๋˜๊ฑฐ๋‚˜ ์ œ๊ฑฐ๋˜์ง€๋Š” ์•Š๋Š” ์ด๋ฒคํŠธ ๋ชฉ๋ก์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. Hibernate๋ฅผ ํ†ตํ•ด ์ด ํ…Œ์ด๋ธ”๋กœ ์ž‘์—…ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์ฝ๊ธฐ ์ „์šฉ ์บ์‹ฑ ์ „๋žต์ด ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

์ฝ๊ธฐ-์“ฐ๊ธฐ (์ฝ๊ธฐ-์“ฐ๊ธฐ). ์ฃผ๋กœ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ์— ์ด ์ „๋žต์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. ๊ทธ๋Ÿฌ๋‚˜ Hibernate๋Š” ์ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๋Š” ์‹œ๋„๋ฅผ ์ถ”์ ํ•  ๊ฒƒ์ด์ง€๋งŒ ์ด๋Ÿฌํ•œ ์‹œ๋„๊ฐ€ ๋งค์šฐ ๋“œ๋ฌผ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค.

๊ฑฐ์˜ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๊ณ  ์ž์ฃผ ์ฝ๊ฑฐ๋‚˜ ์š”์ฒญ๋˜๋Š” ๊ฐ์ฒด๋ฅผ ์ฃผ๋กœ ์บ์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฐœ์ฒด๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น ๊ฐœ์ฒด์— ๋Œ€ํ•œ ์ฝ๊ธฐ-์“ฐ๊ธฐ ์ „๋žต์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋น„์—„๊ฒฉ-์ฝ๊ธฐ-์“ฐ๊ธฐ . ์ด ์ „๋žต์€ ์บ์‹œ์™€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐ„์˜ ์ผ๊ด€์„ฑ์„ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๊ฐ€ ๊ฑฐ์˜ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๊ณ  ์˜ค๋ž˜๋œ ๋ฐ์ดํ„ฐ์˜ ์ž‘์€ ๊ฐ€๋Šฅ์„ฑ์ด ์ค‘์š”ํ•œ ๋ฌธ์ œ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ ์ด ์ „๋žต์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ฝ๊ธฐ-์“ฐ๊ธฐ ์ „๋žต๊ณผ ๋‹ฌ๋ฆฌ ์ด ์ „๋žต์€ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ฝ๊ธฐ์šฉ์œผ๋กœ ์ž ๊ฒจ ์žˆ์ง€ ์•Š๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ๊ฐœ์ฒด๊ฐ€ ํ•œ ๊ณณ์—์„œ ๋ณ€๊ฒฝ๋˜๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ๊ณณ์—์„œ๋Š” ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ด์ „ ๋ฒ„์ „์„ ์ฝ๊ณ  ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ์šฉ์ž๊ฐ€ ์ž์‹ ์˜ ๋Œ“๊ธ€์„ ๋ณ€๊ฒฝํ–ˆ์ง€๋งŒ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋Š” ์–ผ๋งˆ ๋™์•ˆ ์ž์‹ ์˜ ์ด์ „ ๋ฒ„์ „์„ ๊ณ„์† ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค๋ฉด nonstrict-read-write ์ „๋žต์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

ํŠธ๋žœ์žญ์…˜ . ๋“œ๋ฌผ๊ฒŒ ์—…๋ฐ์ดํŠธ๋˜๋Š” ๋™์‹œ ํŠธ๋žœ์žญ์…˜์—์„œ ๋ถ€์‹ค ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•œ ์ฝ๊ธฐ ์ „์šฉ ๋ฐ์ดํ„ฐ์— ์ฃผ๋กœ ์ด ์ „๋žต์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์บ์‹œ์— ๋ฐ์ดํ„ฐ ์ €์žฅ

๊ธฐ์–ตํ•ด์•ผ ํ•  ๋‘ ๋ฒˆ์งธ ์ˆ˜์ค€ ์บ์‹œ์— ๋Œ€ํ•œ ๋˜ ๋‹ค๋ฅธ ์ค‘์š”ํ•œ ์„ธ๋ถ€ ์‚ฌํ•ญ์€ Hibernate๊ฐ€ ํด๋ž˜์Šค ์ž์ฒด์˜ ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฌธ์ž์—ด, ์ˆซ์ž ๋“ฑ์˜ ๋ฐฐ์—ด๋กœ ์ •๋ณด๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๊ฐœ์ฒด ์‹๋ณ„์ž๋Š” ์ด ์ •๋ณด์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋…์ ์œผ๋กœ ์ด๊ฒƒ์€ ๊ฐœ์ฒด์˜ ID๊ฐ€ ํ‚ค์ด๊ณ  ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด์ด ๊ฐ’์ธ ๋งต๊ณผ ๊ฐ™์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1 -> { "Ivanov", 1, null , {1,2,5} }
2 -> { "Petrov", 2, null , {1,2,5} }
3 -> { "Sidorov", 3, null , {1,2,5} }

๊ฐ ๊ฐœ์ฒด๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ์ถ”๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ์–‘์„ ๊ณ ๋ คํ•˜๋ฉด ๋งค์šฐ ํ•ฉ๋ฆฌ์ ์ž…๋‹ˆ๋‹ค.

์œ„์˜ ๋‚ด์šฉ ์™ธ์—๋„ Entity ํด๋ž˜์Šค์˜ ์ข…์†์„ฑ๋„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์บ์‹œ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์œ„์˜ ํด๋ž˜์Šค์ธ Employee๋ฅผ ๊ณ ๋ คํ•˜๋ฉด ๊ฐ€์ ธ์˜ฌ ๋•Œ ์ž‘์—… ์ปฌ๋ ‰์…˜์€ ๋‘ ๋ฒˆ์งธ ์ˆ˜์ค€ ์บ์‹œ๊ฐ€ ์•„๋‹Œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—์„œ ๊ฒ€์ƒ‰ ๋ฉ๋‹ˆ๋‹ค .

์ข…์†์„ฑ๋„ ์บ์‹œํ•˜๋ ค๋ฉด ํด๋ž˜์Šค๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@Entity
@Table(name = "employee")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Employee {
    @Id
    private Integer id;

   @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
   private Set<Task> tasks;
}

๊ทธ๋ฆฌ๊ณ  ๋งˆ์ง€๋ง‰ ์„ธ๋ถ€ ์‚ฌํ•ญ - ๋‘ ๋ฒˆ์งธ ์ˆ˜์ค€ ์บ์‹œ์—์„œ ์ฝ๊ธฐ๋Š” ์›ํ•˜๋Š” ๊ฐœ์ฒด๊ฐ€ ์ฒซ ๋ฒˆ์งธ ์ˆ˜์ค€ ์บ์‹œ์—์„œ ๋ฐœ๊ฒฌ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋งŒ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์บ์‹œ ๋ชจ๋“œ

Hibernate๋Š” ๋งค์šฐ ์œ ์—ฐํ•œ ์บ์‹ฑ ๊ด€๋ฆฌ๋ฅผ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ๊ฐœ๋ณ„ ์„ธ์…˜ ๋˜๋Š” ๊ฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์š”์ฒญ์— ๋Œ€ํ•ด ์บ์‹œ ๋ชจ๋“œ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์€ 5๊ฐ€์ง€ ๋ชจ๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์–ป๋‹ค
  • ๋ฌด์‹œํ•˜๋‹ค
  • ์ •์ƒ
  • ๋†“๋‹ค
  • ์ƒˆ๋กœ ๊ณ ์น˜๋‹ค

์•„๋ž˜ ํ‘œ๋Š” ๊ทธ๋“ค์˜ ์ž‘์—…์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

์บ์‹œ ๋ชจ๋“œ ์„ค๋ช…
์–ป๋‹ค ๋ฐ์ดํ„ฐ๋Š” ์บ์‹œ์—์„œ ์ฝํžˆ์ง€๋งŒ ์ถ”๊ฐ€๋˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.
๋ฌด์‹œํ•˜๋‹ค ์„ธ์…˜์€ ์บ์‹œ์™€ ์ƒํ˜ธ ์ž‘์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
์ •์ƒ ์บ์‹œ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด ์บ์‹œ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
๋†“๋‹ค ๋ฐ์ดํ„ฐ๋Š” ์บ์‹œ์—์„œ ๊ฐ€์ ธ์˜ค์ง€ ์•Š๊ณ  ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.
์ƒˆ๋กœ ๊ณ ์น˜๋‹ค ๋ฐ์ดํ„ฐ๋Š” ์บ์‹œ์—์„œ ๊ฐ€์ ธ์˜ค์ง€ ์•Š๊ณ  ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์ด ๋ชจ๋“œ์—์„œ๋Š” hibernate.cache.use_minimal_puts ์„ค์ •์ด ์ถ”๊ฐ€๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

์„ธ์…˜์— ๋Œ€ํ•œ ์บ์‹œ ๋ชจ๋“œ ์„ค์ •์˜ ์˜ˆ:

session.setCacheMode(CacheMode.GET);
Employee director = session.createQuery("from Employee where id = 4").uniqueResult();

๋˜ํ•œ ์„ธ์…˜ ๋ฐ ์š”์ฒญ์— ๋Œ€ํ•œ ๋ชจ๋“œ ์„ค์ •์˜ ์˜ˆ:

session.setCacheMode(CacheMode.GET);
Query query = session.createQuery("from Employee where id = 4");
query.setCacheMode(CacheMode.IGNORE); // Ignore cache work for this request
Employee director = query.uniqueResult();