Skip to content

Commit

Permalink
fix: 두 개 이상의 쓰레드에서 ThreadLocal에 접근할 때 NPE가 발생하는 문제 해결
Browse files Browse the repository at this point in the history
  • Loading branch information
kong-hana01 committed Oct 11, 2023
1 parent cf4ef72 commit f9272db
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
package org.springframework.transaction.support;

import java.util.HashMap;
import javax.sql.DataSource;
import java.sql.Connection;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;

public abstract class TransactionSynchronizationManager {

private static final ThreadLocal<Map<DataSource, Connection>> resources;
private static final ThreadLocal<Map<DataSource, Connection>> resources = ThreadLocal.withInitial(HashMap::new);

static {
resources = new ThreadLocal<>();
resources.set(new HashMap<>());
private TransactionSynchronizationManager() {
}

private TransactionSynchronizationManager() {}

public static Connection getResource(final DataSource key) {
return resources.get().get(key);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.springframework.transaction.support;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import java.sql.Connection;
import java.sql.SQLException;
Expand All @@ -11,12 +10,19 @@

class TransactionSynchronizationManagerTest {

@Test
void 저장된_데이터소스가_없는_경우_null_반환된다() {
Connection connection = TransactionSynchronizationManager.getResource(TestDataSourceConfig.getInstance());
assertThat(connection).isNull();
}

@Test
void 쓰레드별로_동일한_데이터소스를_가져도_서로_다른_리소스를_가진다() throws InterruptedException {
DataSource dataSource = TestDataSourceConfig.getInstance();
new Thread(() -> {
try {
TransactionSynchronizationManager.bindResource(dataSource, dataSource.getConnection()); // 한 쓰레드에서 connection 바인딩
TransactionSynchronizationManager.bindResource(dataSource,
dataSource.getConnection()); // 한 쓰레드에서 connection 바인딩
} catch (SQLException e) {
throw new RuntimeException(e);
}
Expand All @@ -25,7 +31,6 @@ class TransactionSynchronizationManagerTest {
}).start();

Thread.sleep(500);
assertThatThrownBy(() -> TransactionSynchronizationManager.getResource(dataSource)) // 동일한 키 값으로 조회하더라도 쓰레드가 달라서 NPE 발생
.isInstanceOf(NullPointerException.class);
assertThat(TransactionSynchronizationManager.getResource(dataSource)).isNull(); // 동일한 키 값으로 조회하더라도 쓰레드가 달라서 null 발생
}
}

0 comments on commit f9272db

Please sign in to comment.