use odbc_sys::{AttrConnectionPooling, AttrCpMatch}; use odbc_api::{Connection, ConnectionOptions, Environment, IntoParameter}; use std::{sync::OnceLock}; // To work with threads do I need to share a single Environment ? fn environment_pooling_mssql<'a>() -> &'a Environment { pub static ENV: OnceLock = OnceLock::new(); fn init_env() -> Environment { unsafe { println!("Environment for MSSQL pool"); Environment::set_connection_pooling(AttrConnectionPooling::DriverAware).unwrap(); let mut env = Environment::new().unwrap(); env.set_connection_pooling_matching(AttrCpMatch::Strict) .unwrap(); env } } ENV.get_or_init(init_env) } // If I connect multiple times from different threads, are the connections reused? According to ODBC and Driver ? fn connection_pooling_mssql<'a>() -> Connection<'a> { let env = environment_pooling_mssql(); let connection_string = " Driver={ODBC Driver 18 for SQL Server};\ Server=0.0.0.0;\ UID=SA;\ PWD=12345678;TrustServerCertificate=Yes;Database=mydatabase;\ "; println!("Connection MSSQL pool"); let conn = env .connect_with_connection_string(connection_string, ConnectionOptions::default()) .unwrap(); conn } #[tokio::test] async fn test_odbc_pool_mssql() -> Result<(), Box> { let mut handles = vec![]; for _ in 0..10 { let conn: Connection<'_> = connection_pooling_mssql(); let conn = unsafe { conn.promote_to_send() }; // // The connections are being reused, how can I verify it? // let handle = thread::spawn(move || { // If I create a high number of threads => 10000 and connect in each thread, an error is thrown. // after a number of threads establishing ODBC connections, all connections will fail. // see full log => https://gist.github.com/dertin/da9e195e4cf65a021b1e431fc21e5b97 // let conn: Connection<'_> = connection_pooling_mssql(); let mut prepared = conn.prepare("SELECT * FROM mytable WHERE id=?;").unwrap(); let title = 1; match prepared.execute(&IntoParameter::into_parameter(title)) { Err(e) => println!("{}", e), Ok(None) => println!("No result set generated."), Ok(Some(_cursor)) => {} }; assert!(!conn.is_dead().unwrap()); }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } Ok(()) } fn main() {}