1+ import asyncio
2+ import threading
13from abc import ABC , abstractmethod
24from collections .abc import Callable
35from inspect import Signature , signature
@@ -1510,7 +1512,7 @@ async def fix_migrations(self, dry_run: bool = False, update_database: bool = Tr
15101512class SyncDatabaseConfig (DatabaseConfigProtocol [ConnectionT , PoolT , DriverT ]):
15111513 """Base class for sync database configurations with connection pooling."""
15121514
1513- __slots__ = ("connection_config" , )
1515+ __slots__ = ("_pool_lock" , "connection_config" )
15141516 is_async : "ClassVar[bool]" = False
15151517 supports_connection_pooling : "ClassVar[bool]" = True
15161518 migration_tracker_type : "ClassVar[type[Any]]" = SyncMigrationTracker
@@ -1549,6 +1551,7 @@ def __init__(
15491551 self .driver_features .setdefault ("storage_capabilities" , self .storage_capabilities ())
15501552 self ._promote_driver_feature_hooks ()
15511553 self ._configure_observability_extensions ()
1554+ self ._pool_lock = threading .Lock ()
15521555
15531556 def create_pool (self ) -> PoolT :
15541557 """Create and return the connection pool.
@@ -1558,9 +1561,14 @@ def create_pool(self) -> PoolT:
15581561 """
15591562 if self .connection_instance is not None :
15601563 return self .connection_instance
1561- self .connection_instance = self ._create_pool ()
1562- self .get_observability_runtime ().emit_pool_create (self .connection_instance )
1563- return self .connection_instance
1564+
1565+ with self ._pool_lock :
1566+ if self .connection_instance is not None :
1567+ return self .connection_instance
1568+
1569+ self .connection_instance = self ._create_pool ()
1570+ self .get_observability_runtime ().emit_pool_create (self .connection_instance )
1571+ return self .connection_instance
15641572
15651573 def close_pool (self ) -> None :
15661574 """Close the connection pool."""
@@ -1572,9 +1580,7 @@ def close_pool(self) -> None:
15721580
15731581 def provide_pool (self , * args : Any , ** kwargs : Any ) -> PoolT :
15741582 """Provide pool instance."""
1575- if self .connection_instance is None :
1576- self .connection_instance = self .create_pool ()
1577- return self .connection_instance
1583+ return self .create_pool ()
15781584
15791585 def create_connection (self ) -> ConnectionT :
15801586 """Create a database connection."""
@@ -1709,7 +1715,7 @@ def fix_migrations(self, dry_run: bool = False, update_database: bool = True, ye
17091715class AsyncDatabaseConfig (DatabaseConfigProtocol [ConnectionT , PoolT , DriverT ]):
17101716 """Base class for async database configurations with connection pooling."""
17111717
1712- __slots__ = ("connection_config" , )
1718+ __slots__ = ("_pool_lock" , "connection_config" )
17131719 is_async : "ClassVar[bool]" = True
17141720 supports_connection_pooling : "ClassVar[bool]" = True
17151721 migration_tracker_type : "ClassVar[type[Any]]" = AsyncMigrationTracker
@@ -1750,6 +1756,7 @@ def __init__(
17501756 self .driver_features .setdefault ("storage_capabilities" , self .storage_capabilities ())
17511757 self ._promote_driver_feature_hooks ()
17521758 self ._configure_observability_extensions ()
1759+ self ._pool_lock = asyncio .Lock ()
17531760
17541761 async def create_pool (self ) -> PoolT :
17551762 """Create and return the connection pool.
@@ -1759,9 +1766,14 @@ async def create_pool(self) -> PoolT:
17591766 """
17601767 if self .connection_instance is not None :
17611768 return self .connection_instance
1762- self .connection_instance = await self ._create_pool ()
1763- self .get_observability_runtime ().emit_pool_create (self .connection_instance )
1764- return self .connection_instance
1769+
1770+ async with self ._pool_lock :
1771+ if self .connection_instance is not None :
1772+ return self .connection_instance
1773+
1774+ self .connection_instance = await self ._create_pool ()
1775+ self .get_observability_runtime ().emit_pool_create (self .connection_instance )
1776+ return self .connection_instance
17651777
17661778 async def close_pool (self ) -> None :
17671779 """Close the connection pool."""
@@ -1773,9 +1785,7 @@ async def close_pool(self) -> None:
17731785
17741786 async def provide_pool (self , * args : Any , ** kwargs : Any ) -> PoolT :
17751787 """Provide pool instance."""
1776- if self .connection_instance is None :
1777- self .connection_instance = await self .create_pool ()
1778- return self .connection_instance
1788+ return await self .create_pool ()
17791789
17801790 async def create_connection (self ) -> ConnectionT :
17811791 """Create a database connection."""
0 commit comments