Skip to content

Commit a2c7eeb

Browse files
committed
refactor: 优化sql连接关闭逻辑
1 parent 9f09958 commit a2c7eeb

File tree

1 file changed

+40
-9
lines changed

1 file changed

+40
-9
lines changed

hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/sql/DefaultR2dbcExecutor.java

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,22 @@
88
import org.hswebframework.ezorm.rdb.executor.reactive.r2dbc.R2dbcReactiveSqlExecutor;
99
import org.hswebframework.ezorm.rdb.executor.wrapper.ResultWrapper;
1010
import org.hswebframework.web.api.crud.entity.TransactionManagers;
11-
import org.hswebframework.web.datasource.DataSourceHolder;
12-
import org.hswebframework.web.datasource.R2dbcDataSource;
1311
import org.hswebframework.web.exception.I18nSupportException;
1412
import org.reactivestreams.Publisher;
1513
import org.springframework.beans.factory.annotation.Autowired;
1614
import org.springframework.r2dbc.connection.ConnectionFactoryUtils;
17-
import org.springframework.r2dbc.core.ConnectionAccessor;
1815
import org.springframework.transaction.annotation.Propagation;
1916
import org.springframework.transaction.annotation.Transactional;
2017
import reactor.core.publisher.Flux;
2118
import reactor.core.publisher.Mono;
2219
import reactor.core.publisher.SignalType;
2320

21+
import java.io.Serial;
2422
import java.time.LocalDateTime;
2523
import java.time.ZoneOffset;
2624
import java.util.Date;
2725
import java.util.Map;
26+
import java.util.concurrent.atomic.AtomicBoolean;
2827
import java.util.function.Function;
2928

3029
public class DefaultR2dbcExecutor extends R2dbcReactiveSqlExecutor {
@@ -97,18 +96,50 @@ protected Mono<Connection> getConnection() {
9796

9897
@Override
9998
protected <T> Flux<T> doInConnection(Function<Connection, Publisher<T>> handler) {
99+
Mono<ConnectionCloseHolder> connectionMono = getConnection().map(
100+
connection -> new ConnectionCloseHolder(connection, this::closeConnection));
101+
100102
return Flux.usingWhen(
101-
ConnectionFactoryUtils.getConnection(defaultFactory),
102-
handler,
103-
source -> ConnectionFactoryUtils
104-
.currentConnectionFactory(defaultFactory)
105-
.then()
106-
.onErrorResume(Exception.class, ex -> Mono.from(source.close()))
103+
connectionMono,
104+
holder -> handler.apply(holder.connection),
105+
ConnectionCloseHolder::close,
106+
(it, err) -> it.close(),
107+
ConnectionCloseHolder::close
107108
);
108109

109110
// return super.doWith(handler);
110111
}
111112

113+
static class ConnectionCloseHolder extends AtomicBoolean {
114+
115+
@Serial
116+
private static final long serialVersionUID = -8994138383301201380L;
117+
118+
final transient Connection connection;
119+
120+
final transient Function<Connection, Publisher<Void>> closeFunction;
121+
122+
ConnectionCloseHolder(Connection connection, Function<Connection, Publisher<Void>> closeFunction) {
123+
this.connection = connection;
124+
this.closeFunction = closeFunction;
125+
}
126+
127+
Mono<Void> close() {
128+
return Mono.defer(() -> {
129+
if (compareAndSet(false, true)) {
130+
return Mono.from(this.closeFunction.apply(this.connection));
131+
}
132+
return Mono.empty();
133+
});
134+
}
135+
}
136+
137+
private Publisher<Void> closeConnection(Connection connection) {
138+
return ConnectionFactoryUtils
139+
.currentConnectionFactory(defaultFactory).then()
140+
.onErrorResume(Exception.class, ex -> Mono.from(connection.close()));
141+
}
142+
112143
@Override
113144
protected void releaseConnection(SignalType type, Connection connection) {
114145
//所有方法都被事务接管,不用手动释放

0 commit comments

Comments
 (0)