-
Notifications
You must be signed in to change notification settings - Fork 300
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: TransactionManager 기능을 TransactionSynchronizationManager 와 …
…DataSourceUtils 로 분리
- Loading branch information
Showing
9 changed files
with
229 additions
and
169 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 10 additions & 25 deletions
35
jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,22 @@ | ||
package org.springframework.jdbc.datasource; | ||
|
||
import java.sql.Connection; | ||
import javax.sql.DataSource; | ||
import org.springframework.jdbc.CannotGetJdbcConnectionException; | ||
import org.springframework.jdbc.support.ConnectionHolder; | ||
import org.springframework.transaction.support.TransactionSynchronizationManager; | ||
|
||
import javax.sql.DataSource; | ||
import java.sql.Connection; | ||
import java.sql.SQLException; | ||
|
||
// 4단계 미션에서 사용할 것 | ||
public abstract class DataSourceUtils { | ||
|
||
private DataSourceUtils() {} | ||
|
||
public static Connection getConnection(DataSource dataSource) throws CannotGetJdbcConnectionException { | ||
Connection connection = TransactionSynchronizationManager.getResource(dataSource); | ||
if (connection != null) { | ||
return connection; | ||
} | ||
|
||
try { | ||
connection = dataSource.getConnection(); | ||
TransactionSynchronizationManager.bindResource(dataSource, connection); | ||
return connection; | ||
} catch (SQLException ex) { | ||
throw new CannotGetJdbcConnectionException("Failed to obtain JDBC Connection", ex); | ||
} | ||
private DataSourceUtils() { | ||
} | ||
|
||
public static void releaseConnection(Connection connection, DataSource dataSource) { | ||
try { | ||
connection.close(); | ||
} catch (SQLException ex) { | ||
throw new CannotGetJdbcConnectionException("Failed to close JDBC Connection"); | ||
public static ConnectionHolder getConnectionHolder(DataSource dataSource) throws CannotGetJdbcConnectionException { | ||
final Connection connection = TransactionSynchronizationManager.getResource(dataSource); | ||
if (TransactionSynchronizationManager.isTransactionBegan()) { | ||
return ConnectionHolder.activeTransaction(connection); | ||
} | ||
|
||
return ConnectionHolder.disableTransaction(connection); | ||
} | ||
} |
86 changes: 4 additions & 82 deletions
86
jdbc/src/main/java/org/springframework/jdbc/support/TransactionManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,97 +1,19 @@ | ||
package org.springframework.jdbc.support; | ||
|
||
import java.sql.Connection; | ||
import java.sql.SQLException; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.function.Function; | ||
import javax.sql.DataSource; | ||
import org.springframework.dao.DataAccessException; | ||
import org.springframework.jdbc.support.exception.CannotBeginTransactionException; | ||
import org.springframework.jdbc.support.exception.CannotCommitException; | ||
import org.springframework.jdbc.support.exception.CannotGetConnectionException; | ||
import org.springframework.jdbc.support.exception.CannotRollbackException; | ||
import org.springframework.transaction.support.TransactionSynchronizationManager; | ||
|
||
public class TransactionManager { | ||
|
||
private static final ThreadLocal<Map<DataSource, Connection>> connections = ThreadLocal.withInitial(HashMap::new); | ||
private static final ThreadLocal<Boolean> isTransactionActive = ThreadLocal.withInitial(() -> false); | ||
|
||
public static void beginTransaction() { | ||
isTransactionActive.set(true); | ||
} | ||
|
||
public static ConnectionHolder getConnectionHolder(final DataSource dataSource) { | ||
if (isTransactionActive.get()) { | ||
final Connection connection = guaranteeConnection(dataSource); | ||
beginTransaction(connection); | ||
return ConnectionHolder.activeTransaction(connection); | ||
} | ||
|
||
return ConnectionHolder.disableTransaction(getConnection(dataSource)); | ||
} | ||
|
||
private static Connection guaranteeConnection(final DataSource dataSource) { | ||
if (!connections.get().containsKey(dataSource)) { | ||
Connection connection = getConnection(dataSource); | ||
connections.get().put(dataSource, connection); | ||
return connection; | ||
} | ||
|
||
return connections.get().get(dataSource); | ||
} | ||
|
||
private static Connection getConnection(final DataSource dataSource) { | ||
try { | ||
return dataSource.getConnection(); | ||
} catch (SQLException e) { | ||
throw new CannotGetConnectionException(e.getMessage()); | ||
} | ||
} | ||
|
||
private static void action( | ||
final ConnectionCallBack callBack, | ||
final Function<SQLException, DataAccessException> exceptionSupplier | ||
) { | ||
try { | ||
callBack.action(); | ||
} catch (SQLException e) { | ||
throw exceptionSupplier.apply(e); | ||
} | ||
} | ||
|
||
private static void beginTransaction(final Connection connection) { | ||
action(() -> connection.setAutoCommit(false), | ||
e -> new CannotBeginTransactionException(e.getMessage()) | ||
); | ||
TransactionSynchronizationManager.beginTransaction(); | ||
} | ||
|
||
public static void commit(final DataSource dataSource) { | ||
action(() -> { | ||
if (connections.get().containsKey(dataSource)) { | ||
connections.get().get(dataSource).commit(); | ||
clear(dataSource); | ||
} | ||
}, e -> new CannotCommitException(e.getMessage())); | ||
TransactionSynchronizationManager.commit(dataSource); | ||
} | ||
|
||
public static void rollback() { | ||
action(() -> { | ||
for (final Connection value : connections.get().values()) { | ||
value.rollback(); | ||
} | ||
clear(); | ||
}, e -> new CannotRollbackException(e.getMessage())); | ||
} | ||
|
||
private static void clear(final DataSource dataSource) { | ||
action(() -> { | ||
final Connection connection = connections.get().remove(dataSource); | ||
connection.close(); | ||
}, e -> new DataAccessException(e.getMessage())); | ||
} | ||
|
||
private static void clear() { | ||
connections.get().clear(); | ||
TransactionSynchronizationManager.rollback(); | ||
} | ||
} |
107 changes: 99 additions & 8 deletions
107
.../main/java/org/springframework/transaction/support/TransactionSynchronizationManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,114 @@ | ||
package org.springframework.transaction.support; | ||
|
||
import javax.sql.DataSource; | ||
import java.sql.Connection; | ||
import java.sql.SQLException; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.function.Function; | ||
import javax.sql.DataSource; | ||
import org.springframework.dao.DataAccessException; | ||
import org.springframework.jdbc.support.ConnectionCallBack; | ||
import org.springframework.jdbc.support.exception.CannotBeginTransactionException; | ||
import org.springframework.jdbc.support.exception.CannotCommitException; | ||
import org.springframework.jdbc.support.exception.CannotGetConnectionException; | ||
import org.springframework.jdbc.support.exception.CannotRollbackException; | ||
|
||
public abstract class TransactionSynchronizationManager { | ||
|
||
private static final ThreadLocal<Map<DataSource, Connection>> resources = new ThreadLocal<>(); | ||
private static final ThreadLocal<Map<DataSource, Connection>> connections = ThreadLocal.withInitial(HashMap::new); | ||
private static final ThreadLocal<Boolean> isTransactionActive = ThreadLocal.withInitial(() -> false); | ||
|
||
private TransactionSynchronizationManager() { | ||
} | ||
|
||
public static void beginTransaction() { | ||
isTransactionActive.set(true); | ||
} | ||
|
||
public static boolean isTransactionBegan() { | ||
return isTransactionActive.get(); | ||
} | ||
|
||
public static Connection getResource(final DataSource dataSource) { | ||
if (isTransactionActive.get()) { | ||
final Connection connection = guaranteeConnection(dataSource); | ||
beginTransaction(connection); | ||
return connection; | ||
} | ||
|
||
return getConnection(dataSource); | ||
} | ||
|
||
private static Connection guaranteeConnection(final DataSource dataSource) { | ||
if (!connections.get().containsKey(dataSource)) { | ||
Connection connection = getConnection(dataSource); | ||
connections.get().put(dataSource, connection); | ||
return connection; | ||
} | ||
|
||
private TransactionSynchronizationManager() {} | ||
return connections.get().get(dataSource); | ||
} | ||
|
||
private static Connection getConnection(final DataSource dataSource) { | ||
try { | ||
return dataSource.getConnection(); | ||
} catch (SQLException e) { | ||
throw new CannotGetConnectionException(e.getMessage()); | ||
} | ||
} | ||
|
||
private static void beginTransaction(final Connection connection) { | ||
action(() -> connection.setAutoCommit(false), | ||
e -> new CannotBeginTransactionException(e.getMessage()) | ||
); | ||
} | ||
|
||
private static void action( | ||
final ConnectionCallBack callBack, | ||
final Function<SQLException, DataAccessException> exceptionSupplier | ||
) { | ||
try { | ||
callBack.action(); | ||
} catch (SQLException e) { | ||
throw exceptionSupplier.apply(e); | ||
} | ||
} | ||
|
||
public static void commit(final DataSource dataSource) { | ||
action(() -> { | ||
if (connections.get().containsKey(dataSource)) { | ||
connections.get().get(dataSource).commit(); | ||
clear(dataSource); | ||
} | ||
}, e -> new CannotCommitException(e.getMessage())); | ||
} | ||
|
||
public static void rollback() { | ||
action(() -> { | ||
for (final Connection value : connections.get().values()) { | ||
value.rollback(); | ||
} | ||
clear(); | ||
}, e -> new CannotRollbackException(e.getMessage())); | ||
} | ||
|
||
public static Connection getResource(DataSource key) { | ||
return null; | ||
private static void clear(final DataSource dataSource) { | ||
action(() -> { | ||
final Connection connection = connections.get().remove(dataSource); | ||
clearConnection(connection); | ||
}, e -> new DataAccessException(e.getMessage())); | ||
isTransactionActive.set(false); | ||
} | ||
|
||
public static void bindResource(DataSource key, Connection value) { | ||
private static void clearConnection(final Connection connection) { | ||
action(connection::close, e -> new DataAccessException(e.getMessage())); | ||
} | ||
|
||
public static Connection unbindResource(DataSource key) { | ||
return null; | ||
private static void clear() { | ||
connections.get() | ||
.values() | ||
.forEach(TransactionSynchronizationManager::clearConnection); | ||
connections.get().clear(); | ||
isTransactionActive.set(false); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
48 changes: 0 additions & 48 deletions
48
jdbc/src/test/java/nextstep/support/TransactionManagerTest.java
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.