Goal
- JDBC
- Spring Data JPA
- Persistence Context
JDBC?
Spring JDBC ๋ Spring Framework ์ DB ๊ฐ ํต์ ์ ์ํ ์ธํฐํ์ด์ค๋ก ๊ฐ๋ฐ์๊ฐ ์ฌ์ฉํ๊ณ ์ ํ๋ ๋ฒค๋์ฌ์ ์ ํ์ ๊ด๊ณ์์ด DB ์ ๊ทผ์ด ๊ฐ๋ฅํ๊ฒ ํด์ค๋ค. ํ์ง๋ง JDBC ๋ Persistence Layer ์ ๊ธด๋ฐํ ๊ด๊ณ๋ฅผ ๋งบ๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฐ์๊ฐ ์ง์ Connection ์ค์ ํ๊ฑฐ๋ Statement ๋ฅผ ์ด์ฉํด ์ํ๋ ์์ ์ ์ํ ํ Statement ๋ฅผ ์ง์ ๋ซ์์ค์ผ ํ๋ ๋ฑ์ ๋ฌธ์ ์ ์ด ์ผ๊ธฐ๋ ์ ์์ผ๋ฉฐ, ์ค๋ณต ์ฝ๋์ ์ฌ์์ฐ์ผ๋ก ์ธํด ์ ์ง๋ณด์์ ๋์ด๋๊ฐ ์์นํ๊ฒ ๋๋ค.
Spring Data JPA
ORM(Object Relation Mapper) ์ค ํ๋๋ก, ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ Java ์ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ์ฐ๊ฒฐํด์ฃผ๋ ์ง๊ฒ๋ค๋ฆฌ ์ญํ ์ ํ๋ ์ธํฐํ์ด์ค์ด๋ค. JPA ์ ๊ฐ์ ORM ์ IoC(์ ์ด์ ์ญ์ ) ์ ํตํด JDBC ์์ ๋ฐ์ํ๋ Connection ์ด๋ Statement ๊ด๋ฆฌ ๋ฑ์ ๋ฌธ์ ์ ์ ํด๊ฒฐํ์ฌ ๊ฐ๋ฐ์๊ฐ ์ง์ Query ์์ฑ์ ์ค์ด๊ณ ์ค๋กฏ์ด ๋น์ฆ๋์ค ๋ก์ง์๋ง ์ง์คํ ์ ์๋ค๋ ์ฅ์ ์ด ์๋ค.
์ด๋ฌํ JPA ๋ Hibernate ๋ผ๋ ๊ตฌํ์ฒด๋ฅผ ํตํด ๊ตฌํ๋์ด ์์ผ๋ฉฐ, ์ด๋ฅผ ํตํด ์์์ฑ ์ปจํ ์คํธ(Persistence Context)์ ์ํ Entity ๋ฅผ ์์ฝ๊ฒ ๊ด๋ฆฌ ํ ์ ์๋ค.
Repository / Method Define
@Repository
interface ProductOptionRepository :
JpaRepository<ProductOption, String>,
QuerydslPredicateExecutor<ProductOption> {
fun findProductOptionsByProductIdIn(productIds: List<String>): List<ProductOption>
}
JPA ์ ์ํด ๋ง๋ค์ด์ง Query
select p1_0.id,
p1_0.app_price,
p1_0.name,
p1_0.product_id,
p1_0.registration_date,
p1_0.search_keyword,
p1_0.shelf_life,
p1_0.status,
p1_0.web_price
from product_option p1_0
where p1_0.product_id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
EntityManager / EntityManagerFactory
JPA ์ ์์กด์ฑ์ ์ถ๊ฐํ๊ฒ ๋๋ฉด EntityManager ์ ์ํด ์์์ฑ ์ปจํ ์คํธ๊ฐ ์์ฑ๋๊ณ , Entity ๋ก ๋ฑ๋ก๋ ๊ฐ์ฒด๋ค์ ์์์ฑ ์ปจํ ์คํธ์ ์ํด ์๋ช ์ฃผ๊ธฐ๊ฐ ๊ด๋ฆฌ๋๋ฉฐ, EntityManager ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํด ๊ด๋ฆฌ๋๋ค.
์ด ๋ EntityManagerFactory ๋ฅผ ํตํด EntityManager ๊ฐ ์์ฑ๋๋๋ฐ, EntityManagerFactory ๋ Thread-safe, EntityManager ๋ Thread-safe ํ์ง ๋ชปํ๋ค. ๋๋ฌธ์ EntityManager ๋ ์ค๋ ๋ ๋น ํ๋๋ง ์กด์ฌํ๊ฒ ๋๋ค.
๋ํ EntityManager ๋ Transaction ์ํ ์, ๋ด๋ถ์ ์ผ๋ก Connection Pool ์์ ํ๋์ Connection ์ ์ด์ฉํ๊ณ Transaction ์ด ์ข ๋ฃ๋๋ฉด Connection ์ ๋ค์ Connection Pool ๋ก ๋ฐํํ๋ค.
๐ EntityManagerFactory ๋ ์ ์์ฑ ๋น์ฉ์ด ๋น์๊น?
> ์ถ์ธกํ๊ฑด๋ฐ ์๋ง JDBC ์ ๋น์ทํ๊ฒ DB ์ ์ฐ๊ฒฐํ๊ธฐ ์ํ ๊ณผ์ ์ ๋ง์ ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ธ๊ฑธ๊น? ์คํฐ๋ ๋ ์ง๋ฌธ ํด์ผ๊ฒ ๋ค.
// ์ ํ๋ฆฌ์ผ์ด์
์คํ ์, EntityFactoryManager ์ด๊ธฐํ
public abstract class AbstractEntityManagerFactoryBean implements
FactoryBean<EntityManagerFactory>, BeanClassLoaderAware, BeanFactoryAware, BeanNameAware,
InitializingBean, DisposableBean, EntityManagerFactoryInfo, PersistenceExceptionTranslator, Serializable {
private EntityManagerFactory buildNativeEntityManagerFactory() {
EntityManagerFactory emf;
try {
emf = createNativeEntityManagerFactory();
}
catch (PersistenceException ex) {
if (ex.getClass() == PersistenceException.class) {
// Plain PersistenceException wrapper for underlying exception?
// Make sure the nested exception message is properly exposed,
// along the lines of Spring's NestedRuntimeException.getMessage()
Throwable cause = ex.getCause();
if (cause != null) {
String message = ex.getMessage();
String causeString = cause.toString();
if (!message.endsWith(causeString)) {
ex = new PersistenceException(message + "; nested exception is " + causeString, cause);
}
}
}
if (logger.isErrorEnabled()) {
logger.error("Failed to initialize JPA EntityManagerFactory: " + ex.getMessage());
}
throw ex;
}
JpaVendorAdapter jpaVendorAdapter = getJpaVendorAdapter();
if (jpaVendorAdapter != null) {
jpaVendorAdapter.postProcessEntityManagerFactory(emf);
}
if (logger.isInfoEnabled()) {
logger.info("Initialized JPA EntityManagerFactory for persistence unit '" + getPersistenceUnitName() + "'");
}
return emf;
}
}
Persistence Context
EntityManager ๋ Transaction ์์ ์ํ ์ ์์์ฑ ์ปจํ ์คํธ์ Entity ๋ฅผ ๋ด๊ณ , ํด๋น Entity ์ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ด๋ฆฌํ๋ค. ๊ทธ๋ ๋ค๋ฉด ์ฌ๊ธฐ์ ์์์ฑ ์ปจํ ์คํธ(Persistence Context) ๋ ๋ฌด์์ ์๋ฏธํ ๊น?
์์์ฑ ์ปจํ ์คํธ๋ '์๊ตฌ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ํ๊ฒฝ' ์ด๋ผ๋ ๋ป์ผ๋ก, ์ ํ๋ฆฌ์ผ์ด์ ๊ณผ DB ์ฌ์ด์ 1์ฐจ ์บ์ ๊ฐ์ ์๋ฏธ๋ฅผ ๊ฐ์ง๋ค.
๋จ์ํ ์บ์์ ๊ฐ์ด ์๋์ผ๋ก ๋๋๋ ๊ฒ์ด ์๋ ์ปจํ ์คํธ์ ๋ฑ๋ก๋ Entity ์ธ์คํด์ค๋ ๋ณ๊ฒฝ ๊ฐ์ง, ๋์ผ์ฑ ๋ณด์ฅ, ์ฐ๊ธฐ ์ง์ฐ ๋ฑ ์ฌ๋ฌ ํธ์ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค. ๋ํ, ํด๋น Transaction ์์ ์ํ๋์ด์ผ ํ ๋ชจ๋ Query ๊ฐ commit ๋ ๋ค์ Entity ์ ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ค. (RDBMS ์ Rollback ๊ณผ ๋น์ทํ๋ค.)
ํ์ง๋ง ์์์ฑ ์ปจํ ์คํธ์ ํฌํจ๋์ง ์๋ ์ํฐํฐ๋ (Transaction ์ ํ ๋ฒ์๋ฅผ ๋ฒ์ด๋ ๊ฒฝ์ฐ) ์กฐํ ์ ์์ธ๊ฐ ๋ฐ์ํ๋ค.
์์์ฑ ์ปจํ ์คํธ์ ๊ด๋ฆฌ๋๋ Entity Instance
@Service
class ProductService(
private val productOptionRepository: ProductOptionRepository
) {
@Transactional
fun updateProductOption(product: Product, productOption: ProductOption) {
val productOption = productOptionRepository.findById("10")
.orElseThrow { IllegalArgumentException("์ ํ ์ต์
์ด ์กด์ฌํ์ง ์์ต๋๋ค.") }
val product = productOption.product
// EntityManager ์ ์ํด Dirty Checking
// ๋ณ๊ฒฝ์ด ํ์ธ๋๋ฉด ๋ณ๊ฒฝ ๋ด์ฉ์ด DB ์ ๋ฐ์๋๋ค.
productOption.name = "256GB"
product?.name = "[์ ์ ํ] ์์ดํฐ15"
}
}
Transaction ์ ํ ๋ฒ์๋ฅผ ๋์ด๊ฐ๋ ๊ฒฝ์ฐ ์์ธ ๋ฐ์
@Service
class ProductService(
private val productOptionRepository: ProductOptionRepository
) {
@Transactional
fun mapToDto(productOption: ProductOption): ProductRespDto {
val productOption = productOptionRepository.findById("10")
.orElseThrow { IllegalArgumentException("์ ํ ์ต์
์ ์ฐพ์ ์ ์์ต๋๋ค.") }
return ProductRespDto(productOption)
}
}
class ProductRespDto(
productOption: ProductOption
) {
// Transaction ์ ์ ํ ๋ฒ์๋ฅผ ๋ฒ์ด๋๋ฉด Join ํ๊ณ ์๋ ๋ฐ์ดํฐ ์ ๊ทผ ์ ์์ธ ๋ฐ์
val productName: String = productOption.product.name
val productOptionName: String = productOption.name
}
์์์ฑ ์ปจํ ์คํธ์ ์ด์
- 1์ฐจ ์บ์
- ์์์ฑ ์ปจํ ์คํธ์์ ๊ด๋ฆฌ๋๊ณ ์๋ Entity ์ธ์คํด์ค๋ฅผ ํ์ฌ Transaction ์์ ๋ค์ ์กฐํํ ๋, ์์์ฑ ์ปจํ ์คํธ์์ ํด๋น ์ธ์คํด์ค๋ฅผ ์กฐํํ๋๋ก ํ๋ค. ๋ง์ฝ ์์์ฑ ์ปจํ ์คํธ์ ์ฐพ๊ณ ์ ํ๋ ์ธ์คํด์ค๊ฐ ์กด์ฌํ์ง ์๋๋ค๋ฉด DB ๋ฅผ ํตํด ์กฐํํ์ฌ ์์์ฑ ์ปจํ ์คํธ์ ์ถ๊ฐํ๊ณ , ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ด๋ฆฌํ๋ค.
- ๋์ผ์ฑ ๋ณด์ฅ
val person1 = em.find(Person::class.java, 1L)
val person2 = em.find(Person::class.java, 1L)
// ์์์ฑ ์ปจํ
์คํธ์ ์ํด ๊ด๋ฆฌ๋๋ Entity ์ธ์คํด์ค๋ ๋์ผํ ํธ๋์ น์
๋ด์์ ์กฐํ ํ ๊ฒฝ์ฐ ๊ฐ์ฒด์ ๋์ผ์ฑ์ ๋ณด์ฅํ๋ค.
println(person1 == person2)
- ์ฐ๊ธฐ ์ง์ฐ
- EntityManager ๋ ํธ๋์ญ์ ์ Commit ํ๊ธฐ ์ ์ ๋ด๋ถ์ ์ฟผ๋ฆฌ ์ ์ฅ์์ ํด๋น ํธ๋์ญ์ ์์ ํธ์ถ๋ Insert Query ๋ฅผ ๋ชจ์๋๊ณ , Commit ์ด ๋๋ ์์ ์ ์ ์ฅ์์ ์ ์ฅํ Insert Query ๋ฅผ DB ๋ก ์ ์กํ๋๋ฐ ์ด๋ฅผ ์ฐ๊ธฐ ์ง์ฐ์ด๋ผ๊ณ ํ๋ค.
- ๋ณ๊ฒฝ ๊ฐ์ง(Dirty Check)
- ์์์ฑ ์ปจํ
์คํธ์ ๊ด๋ฆฌ๋๋ Entity ์ธ์คํด์ค๋ค์ ๋ณ๊ฒฝ์ ๊ฐ์งํ๊ณ , ๋ณ๋๋ก Update Query ๋ฅผ ๋ ๋ฆฌ์ง ์์๋ DB ๋ก ์ ์ก๋๋ค.
- flush() ๋ฐ์
- 1์ฐจ ์บ์ ๋ฐ์ดํฐ์ Entity ์ ์ค๋ ์ท์ ๋น๊ต
- Update Query ์์ฑ
- flush(), ์์์ฑ ์ปจํ ์คํธ์ ์๋ ๊ฐ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก ์ ์ก
- commit()
- ์์์ฑ ์ปจํ
์คํธ์ ๊ด๋ฆฌ๋๋ Entity ์ธ์คํด์ค๋ค์ ๋ณ๊ฒฝ์ ๊ฐ์งํ๊ณ , ๋ณ๋๋ก Update Query ๋ฅผ ๋ ๋ฆฌ์ง ์์๋ DB ๋ก ์ ์ก๋๋ค.
Entity Lifecycle
์์์ฑ ์ปจํ ์คํธ์ ์ํด ๊ด๋ฆฌ๋๋ Entity ๋ ๋ค์๊ณผ ๊ฐ์ ์์์ฑ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ฑฐ์น๊ฒ ๋๋ค.
- ๋น์์ ๊ฐ์ฒด(new / transient) : ์์์ฑ ์ปจํ ์คํธ์ ๊ด๊ณ๊ฐ ์๋ ์ํ
- ์์ ๊ฐ์ฒด(managed) : ์์์ฑ ์ปจํ ์คํธ์ ์ํด ๊ด๋ฆฌ๋๋ Entity ์ธ์คํด์ค๋ก ํด๋น ์ธ์คํด์ค๋ Dirty Check ์ ์ํด ์๋์ผ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ํ๋๋ค.
- ์ค์์ ๊ฐ์ฒด(detached) : ์์์ฑ ์ปจํ ์คํธ์ ๊ด๋ฆฌ๋๋ค๊ฐ ๋ถ๋ฆฌ๋ ์ธ์คํด์ค๋ก ๋์ด์ ์ถ์ ๋์ง ์๋๋ค.
- ์ญ์ ๊ฐ์ฒด(removed) : ์ธ์ ์ ์ํด delete() ๋ฉ์๋๊ฐ ํธ์ถ๋๋ฉด ์ญ์ ๋ ์ธ์คํด์ค๋ก ์ธ์งํ๋ค. ํ์ง๋ง Entity ์ธ์คํด์ค๋ EntityManager ์ ์์ ๋จ์๊ฐ ์ข ๋ฃ๋ ๋๊น์ง ์์์ ์ปจํ ์คํธ์ ์กด์ฌํ๋ค.
Transaction
Transaction ์ด๋ ํ๋์ ์์ ๋จ์๋ผ๋ ์๋ฏธ๋ก ์ฌ๋ฌ Query ๋ฅผ ํ๋์ Transaction ์ผ๋ก ๋ฌถ์ด Commit ํ๋ฉด DB ์ ๋ฐ์๋๋ค. ๋ง์ฝ Transaction ์ํ ๋์ค ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ฉด Rollback ํ์ฌ ๋ฐ์ดํฐ์ ์์์ฑ์ ์ ์งํ๋๋ก ํ๋ค.
์ด๋ฌํ Transaction ์ ํน์ฑ์ ๋ค์๊ณผ ๊ฐ๋ค.
- ์์์ฑ : Transaction ๋ด์ ์ง์๋ ๋ชจ๋ ์ฑ๊ณตํ๊ฑฐ๋ ๋ชจ๋ ์คํจํด์ผ ํ๋ค.
- ์ผ๊ด์ฑ : ์์ ์ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๊ฐ ํญ์ ์ผ๊ด์ฑ์ด์ ์ง๋์ด์ผ ํ๋ค. (๋ฌด๊ฒฐ์ฑ ์ ์ฝ์กฐ๊ฑด ๋ฑ)
- ๋ ๋ฆฝ์ฑ : ์ฌ๋ฌ Transaction ์ด ์ํ ๋๋๋ผ๋ ๊ฐ๊ฐ์ Transaction ์ ์๋ก ์ํฅ์ ๋ฏธ์น์ง ์์์ผ ํ๋ค.
- ์ง์์ฑ : Transaction ์ด ์ฑ๊ณต์ ์ผ๋ก ์ํ์ ๋ง์น๋ฉด ๋ณ๊ฒฝ๋ ๋ฐ์ดํฐ๊ฐ DB ์๊ตฌ์ ์ผ๋ก ๋ณด์กด๋์ด์ผ ํ๋ค.
@Transactional
JPA ๋ Transaction ์ ์์์ฑ, ์ผ๊ด์ฑ, ๋ ๋ฆฝ์ฑ, ์ง์์ฑ์ ์ ์งํ๊ธฐ ์ํด @Transactional ์ด๋ ธํ ์ด์ ์ ์ง์ํ๋ค.
ํด๋น ์ด๋ ธํ ์ด์ ์ Transaction ์ํ ์ ์ ํ ์ ํ, ๊ฒฉ๋ฆฌ ์์ค, read-only, Rollback ๊ท์น ๋ฑ์ ์ค์ ํ ์ ์์ผ๋ฉฐ, Class ํน์ Method ์ ์ง์ ํ์ฌ ์ฌ์ฉ ํ ์ ์๋ค.
@Transactional
class ProductService {
@Transactional(readonly = true)
fun findProduct(id: String): Product {
...
}
}
์ ํ ์ ํ
- REQUIRED
- @Transactional ์ ๊ธฐ๋ณธ ์ ํ ์ ํ ์ค์ ์ด๋ค. ๋๋ฌธ์ @Transactional ์ด๋ ธํ ์ด์ ์ฌ์ฉ ์, ์๋ก์ด Transaction ์ ์์ฑํ๋ค.
- SUPPORTS
- ํ์ฌ ํ์ฑํ๋ Transaction ์ด ์กด์ฌํ๋์ง ํ์ธํ๊ณ , ์กด์ฌํ๋ ๊ฒฝ์ฐ ๊ธฐ์กด Transction ์, ์กด์ฌํ์ง ์๋ ๊ฒฝ์ฐ Transaction ์ ์ฌ์ฉํ์ง ์๋๋ก ํ๋ค.
- MANDATORY
- ํ์ฑํ๋ Transaction ์ด ์กด์ฌํด์ผ ํ๋ฉฐ, ๊ธฐ์กด Transaction ์ ์ฌ์ฉํ๋ค. ๋ง์ฝ ํ์ฑ Transaction ์ด ์กด์ฌํ์ง ์๋ ๊ฒฝ์ฐ ์์ธ๋ฅผ ๋ฐ์ํ๋ค.
if (isExistingTransaction()) {
if (isValidateExistingTransaction()) {
validateExisitingAndThrowExceptionIfNotValid();
}
return existing;
}
throw IllegalTransactionStateException;
- REQUIRES_NEW
- ํ์ฌ Transaction ์ด ์กด์ฌํ๋ ๊ฒฝ์ฐ ๊ธฐ์กด Transaction ์ ์ข ๋ฃํ๊ณ , ์งํ ์ค์ธ ๋น์ฆ๋์ค ๋ก์ง์ ์๋ก์ด Transaction ์ ์์ฑํ์ฌ ์ํํ๋๋ก ํ๋ค.
- NOT_SUPPOERTED
- ํ์ฌ Transaction ์ด ์กด์ฌํ๋ ๊ฒฝ์ฐ ๊ธฐ์กด Transaction ์ ์ข ๋ฃํ๊ณ , ์งํ ์ค์ธ ๋น์ฆ๋์ค ๋ก์ง์ Transaction ์์ด ์ํํ๋๋ก ํ๋ค.
- NEVER
- ํด๋น ์ ํ ์ ํ์ผ๋ก ์ค์ ํ๋ ๊ฒฝ์ฐ, ํด๋์ค ๋ฐ ๋ฉ์๋ ํธ์ถ ์ ํ์ฑ๋ Transaction ์ด ์กด์ฌํ๋ ๊ฒฝ์ฐ ์์ธ๋ฅผ ๋ฐ์ํ๋ค.
if (isExistingTransaction()) {
throw IllegalTransactionStateException;
}
return emptyTransaction;
- NESTED
- ํ์ฌ Transaction ์ด ์กด์ฌํ๋ ๊ฒฝ์ฐ ๋ถ๋ชจ Transaction ์ Commit / Rollback ์ ์ํฅ์ ๋ฐ๊ณ , ์์ ์ Commit / Rollback ์ ๋ํด์๋ ์ํฅ์ ๋ฐ์ง ์๋๋ค. ์ฆ, ์ฃผ๋๊ถ์ด ๋ถ๋ชจ Transaction ์ ์๋ค.
๊ฒฉ๋ฆฌ ์์ค
๊ฒฉ๋ฆฌ ์์ค์ ACID ํน์ฑ ์ค ํ๋๋ก, ๋์ Transaction ๋ฅผ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ ์ง์ ๋ํด ์ค์ ํ๋ค.
์ด๋ฌํ ๊ฒฉ๋ฆฌ ์์ค์ ๋ค์์ ์ํฅ๋ ฅ์ ๊ฐ์ง๋ค.
- DIrty Read : ๋์ Transaction ์ Commit ๋์ง ์์ ๋ณ๊ฒฝ ์ฌํญ์ ์กฐํํ๋ค.
- Nonrepeatable Read : ๋์ Transaction ์ด ๋์ผํ ํ์ ์ ๋ฐ์ดํธ ๋ฐ ์ปค๋ฐ์ ํ๋ ๊ฒฝ์ฐ ํ์ ์ฝ์ ๋ ๋ค๋ฅธ ๊ฐ์ ๊ฐ์ ธ์จ๋ค.
- Phantom Read : ๋ค๋ฅธ Transaction ์ ๋ฒ์ ์ค ์ผ๋ถ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ์ ๊ฑฐํ๋ค. ํน์ Commit ํ๋ ๊ฒฝ์ฐ ๋ฒ์์ ๋ํ Query ๋ฅผ ๋ค์ ์คํํ ํ ๋ค๋ฅธ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์จ๋ค.
- DEFAULT
- @Transactional ์ ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ ์์ค์ด๋ค. ์ด๋ RDBMS ์ ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ ์์ค์ด๋ค.
- READ_UNCOMMITED
- ๊ฐ์ฅ ๋ฎ์ ๊ฒฉ๋ฆฌ ์์ค์ผ๋ก ๋์ ์์ธ์ค๋ฅผ ํ์ฉํ๋ค. ๋๋ฌธ์ ๋์์ฑ ๋ถ์์ฉ์ด ๋ชจ๋ ๋ฐ์ํ๋๋ฐ, ํด๋น ๊ฒฉ๋ฆฌ ์์ค์ผ๋ก ์ค์ ๋๋ ๊ฒฝ์ฐ ๋์ Transaction ์ํ ์, ๋ค๋ฅธ Transaction ์์ Commit ๋์ง ์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด ๋์์ฑ ๋ฌธ์ ๋ฅผ ๋ฐ์์ํจ๋ค. ๊ทธ๋์ ์คํํ ๋ ๋ง๋ค ๋ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๋ค๋ ์ ์ ์ ์ํด์ผ ํ๋ค.
- READ_COMMITED
- ๋์ Transaction ์ํ ์ ๋ค๋ฅธ Transaction ์ด Commit ๋ ์ดํ ๋ณ๊ฒฝ๋ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๋๋ก ํ๋ ๊ฒฉ๋ฆฌ ์์ค์ผ๋ก Dirty Read ๋ฅผ ๋ฐฉ์งํ๋ค. ๋ค๋ง Nonreapeatable Read / Phantom Read ๋ ์ฌ์ ํ ๋ฐฉ์งํ์ง ๋ชปํด ๋์์ฑ ๋ฌธ์ ๊ฐ ๋ฐ์ ํ ์ ์๋ค.
- REPEATABLE_READ
- Dirty Read ๋ฐ Nonreapeatable Read ๋ฅผ ๋ฐฉ์งํ๋ ๊ฒฉ๋ฆฌ ์์ค์ด๋ค. ์ฆ, ๋์ Transaction ์ํ ์ค Commit ๋์ง ์์ ๋ด์ฉ์ ์ํฅ์ ๋ฐ์ง ์๋๋ค. ๋ํ, ์ ๋ฐ์ดํธ ์์ค์ ๋ฐฉ์งํ๊ธฐ ์ํด ๋์ Transaction ์ํ ์ ๋์ ์์ธ์ค๋ฅผ ํ์ฉํ์ง ์๋๋ค.
- SERIALIZABLE
- ๋ชจ๋ ๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ง๋ง Transaction ์ ์์ฐจ์ ์ผ๋ก ์คํํ๊ธฐ ๋๋ฌธ์ ์์ธ์ค ์๋๊ฐ ๊ฐ์ฅ ๋ฎ๋ค.
'Programming > Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[QueryDSL] NoSuchMethodError Trouble Shooting (0) | 2023.02.22 |
---|---|
Criteria API (0) | 2023.01.28 |
Spring Bean / IoC Container / DI (1) | 2023.01.21 |
Spring | Spring Framework ? (0) | 2020.08.02 |
IntelliJ | Spring MVC + Maven ํ๋ก์ ํธ ๋ง๋ค๊ธฐ (Oracle) (0) | 2020.07.26 |