|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2023 the original author or authors. |
| 2 | + * Copyright 2002-2025 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
|
21 | 21 | import java.util.List;
|
22 | 22 | import java.util.Map;
|
23 | 23 | import java.util.Set;
|
| 24 | +import java.util.concurrent.locks.Lock; |
| 25 | +import java.util.concurrent.locks.ReentrantLock; |
24 | 26 |
|
25 | 27 | import javax.sql.DataSource;
|
26 | 28 |
|
@@ -66,6 +68,9 @@ public abstract class AbstractJdbcCall {
|
66 | 68 | /** List of RefCursor/ResultSet RowMapper objects. */
|
67 | 69 | private final Map<String, RowMapper<?>> declaredRowMappers = new LinkedHashMap<>();
|
68 | 70 |
|
| 71 | + /** Lock for the compilation step. */ |
| 72 | + private final Lock compilationLock = new ReentrantLock(); |
| 73 | + |
69 | 74 | /**
|
70 | 75 | * Has this operation been compiled? Compilation means at least checking
|
71 | 76 | * that a DataSource or JdbcTemplate has been provided.
|
@@ -284,24 +289,30 @@ public void addDeclaredRowMapper(String parameterName, RowMapper<?> rowMapper) {
|
284 | 289 | * @throws org.springframework.dao.InvalidDataAccessApiUsageException if the object hasn't
|
285 | 290 | * been correctly initialized, for example if no DataSource has been provided
|
286 | 291 | */
|
287 |
| - public final synchronized void compile() throws InvalidDataAccessApiUsageException { |
288 |
| - if (!isCompiled()) { |
289 |
| - if (getProcedureName() == null) { |
290 |
| - throw new InvalidDataAccessApiUsageException("Procedure or Function name is required"); |
291 |
| - } |
292 |
| - try { |
293 |
| - this.jdbcTemplate.afterPropertiesSet(); |
294 |
| - } |
295 |
| - catch (IllegalArgumentException ex) { |
296 |
| - throw new InvalidDataAccessApiUsageException(ex.getMessage()); |
297 |
| - } |
298 |
| - compileInternal(); |
299 |
| - this.compiled = true; |
300 |
| - if (logger.isDebugEnabled()) { |
301 |
| - logger.debug("SqlCall for " + (isFunction() ? "function" : "procedure") + |
302 |
| - " [" + getProcedureName() + "] compiled"); |
| 292 | + public final void compile() throws InvalidDataAccessApiUsageException { |
| 293 | + this.compilationLock.lock(); |
| 294 | + try { |
| 295 | + if (!isCompiled()) { |
| 296 | + if (getProcedureName() == null) { |
| 297 | + throw new InvalidDataAccessApiUsageException("Procedure or Function name is required"); |
| 298 | + } |
| 299 | + try { |
| 300 | + this.jdbcTemplate.afterPropertiesSet(); |
| 301 | + } |
| 302 | + catch (IllegalArgumentException ex) { |
| 303 | + throw new InvalidDataAccessApiUsageException(ex.getMessage()); |
| 304 | + } |
| 305 | + compileInternal(); |
| 306 | + this.compiled = true; |
| 307 | + if (logger.isDebugEnabled()) { |
| 308 | + logger.debug("SqlCall for " + (isFunction() ? "function" : "procedure") + |
| 309 | + " [" + getProcedureName() + "] compiled"); |
| 310 | + } |
303 | 311 | }
|
304 | 312 | }
|
| 313 | + finally { |
| 314 | + this.compilationLock.unlock(); |
| 315 | + } |
305 | 316 | }
|
306 | 317 |
|
307 | 318 | /**
|
|
0 commit comments