此頁面提供最佳做法和特定程式設計語言的程式碼範例,幫助您建立應用程式,有效率地使用 Cloud SQL 資料庫連線。
這些範例是完整網頁應用程式的摘錄內容,您可以在 GitHub 上取得完整應用程式。瞭解詳情。
如需逐步操作說明,瞭解如何執行連線至 Cloud SQL 的範例網頁應用程式,請點選下列適用於您環境的連結:
- 快速入門導覽課程:從本機電腦建立連線
- 從 Compute Engine 連線的快速入門
- 快速入門導覽課程:從 Cloud Run 連線
- 快速入門導覽課程:從 Cloud Run functions 連線
- 從 Google Kubernetes Engine 連線的快速入門指南
連線集區
連線集區是資料庫連線的快取,系統會共用和重複使用此快取,藉此縮短連線延遲時間和改善連線效率。當您的應用程式需要資料庫連線時,會從集區暫時借出連線;使用完畢後,應用程式會將連線還給集區,以便下次需要資料庫連線時能重複使用。
透過 TCP 連線
Python
如要查看網頁應用程式中的程式碼片段,請參閱 GitHub 上的 README。
import os import ssl import sqlalchemy def connect_tcp_socket() -> sqlalchemy.engine.base.Engine: """Initializes a TCP connection pool for a Cloud SQL instance of Postgres.""" # Note: Saving credentials in environment variables is convenient, but not # secure - consider a more secure solution such as # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help # keep secrets safe. db_host = os.environ[ "INSTANCE_HOST" ] # e.g. '127.0.0.1' ('172.17.0.1' if deployed to GAE Flex) db_user = os.environ["DB_USER"] # e.g. 'my-db-user' db_pass = os.environ["DB_PASS"] # e.g. 'my-db-password' db_name = os.environ["DB_NAME"] # e.g. 'my-database' db_port = os.environ["DB_PORT"] # e.g. 5432 pool = sqlalchemy.create_engine( # Equivalent URL: # postgresql+pg8000://<db_user>:<db_pass>@<db_host>:<db_port>/<db_name> sqlalchemy.engine.url.URL.create( drivername="postgresql+pg8000", username=db_user, password=db_pass, host=db_host, port=db_port, database=db_name, ), # ... ) return pool
Java
如要查看網頁應用程式中的程式碼片段,請參閱 GitHub 上的 README。
注意:
- CLOUD_SQL_CONNECTION_NAME 應表示為 <MY-PROJECT>:<INSTANCE-REGION>:<INSTANCE-NAME>
- 使用 ipTypes=PRIVATE 引數會強制 SocketFactory 連線至執行個體相關聯的私人 IP
- 請參閱 pom.xml 檔案的 JDBC 通訊端處理站版本規定。
import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import javax.sql.DataSource; public class TcpConnectionPoolFactory extends ConnectionPoolFactory { // Note: Saving credentials in environment variables is convenient, but not // secure - consider a more secure solution such as // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help // keep secrets safe. private static final String DB_USER = System.getenv("DB_USER"); private static final String DB_PASS = System.getenv("DB_PASS"); private static final String DB_NAME = System.getenv("DB_NAME"); private static final String INSTANCE_HOST = System.getenv("INSTANCE_HOST"); private static final String DB_PORT = System.getenv("DB_PORT"); public static DataSource createConnectionPool() { // The configuration object specifies behaviors for the connection pool. HikariConfig config = new HikariConfig(); // The following URL is equivalent to setting the config options below: // jdbc:postgresql://<INSTANCE_HOST>:<DB_PORT>/<DB_NAME>?user=<DB_USER>&password=<DB_PASS> // See the link below for more info on building a JDBC URL for the Cloud SQL JDBC Socket Factory // https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory#creating-the-jdbc-url // Configure which instance and what database user to connect with. config.setJdbcUrl(String.format("jdbc:postgresql://%s:%s/%s", INSTANCE_HOST, DB_PORT, DB_NAME)); config.setUsername(DB_USER); // e.g. "root", "postgres" config.setPassword(DB_PASS); // e.g. "my-password" // ... Specify additional connection properties here. // ... // Initialize the connection pool using the configuration object. return new HikariDataSource(config); } }
Node.js
如要查看網頁應用程式中的程式碼片段,請參閱 GitHub 上的 README。
const Knex = require('knex'); const fs = require('fs'); // createTcpPool initializes a TCP connection pool for a Cloud SQL // instance of Postgres. const createTcpPool = async config => { // Note: Saving credentials in environment variables is convenient, but not // secure - consider a more secure solution such as // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help // keep secrets safe. const dbConfig = { client: 'pg', connection: { host: process.env.INSTANCE_HOST, // e.g. '127.0.0.1' port: process.env.DB_PORT, // e.g. '5432' user: process.env.DB_USER, // e.g. 'my-user' password: process.env.DB_PASS, // e.g. 'my-user-password' database: process.env.DB_NAME, // e.g. 'my-database' }, // ... Specify additional properties here. ...config, }; // Establish a connection to the database. return Knex(dbConfig); };
Go
如要查看網頁應用程式中的程式碼片段,請參閱 GitHub 上的 README。
package cloudsql import ( "database/sql" "fmt" "log" "os" // Note: If connecting using the App Engine Flex Go runtime, use // "github.com/jackc/pgx/stdlib" instead, since v5 requires // Go modules which are not supported by App Engine Flex. _ "github.com/jackc/pgx/v5/stdlib" ) // connectTCPSocket initializes a TCP connection pool for a Cloud SQL // instance of Postgres. func connectTCPSocket() (*sql.DB, error) { mustGetenv := func(k string) string { v := os.Getenv(k) if v == "" { log.Fatalf("Fatal Error in connect_tcp.go: %s environment variable not set.", k) } return v } // Note: Saving credentials in environment variables is convenient, but not // secure - consider a more secure solution such as // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help // keep secrets safe. var ( dbUser = mustGetenv("DB_USER") // e.g. 'my-db-user' dbPwd = mustGetenv("DB_PASS") // e.g. 'my-db-password' dbTCPHost = mustGetenv("INSTANCE_HOST") // e.g. '127.0.0.1' ('172.17.0.1' if deployed to GAE Flex) dbPort = mustGetenv("DB_PORT") // e.g. '5432' dbName = mustGetenv("DB_NAME") // e.g. 'my-database' ) dbURI := fmt.Sprintf("host=%s user=%s password=%s port=%s database=%s", dbTCPHost, dbUser, dbPwd, dbPort, dbName) // dbPool is the pool of database connections. dbPool, err := sql.Open("pgx", dbURI) if err != nil { return nil, fmt.Errorf("sql.Open: %w", err) } // ... return dbPool, nil }
C#
如要查看網頁應用程式中的程式碼片段,請參閱 GitHub 上的 README。
using Npgsql; using System; namespace CloudSql { public class PostgreSqlTcp { public static NpgsqlConnectionStringBuilder NewPostgreSqlTCPConnectionString() { // Equivalent connection string: // "Uid=<DB_USER>;Pwd=<DB_PASS>;Host=<INSTANCE_HOST>;Database=<DB_NAME>;" var connectionString = new NpgsqlConnectionStringBuilder() { // Note: Saving credentials in environment variables is convenient, but not // secure - consider a more secure solution such as // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help // keep secrets safe. Host = Environment.GetEnvironmentVariable("INSTANCE_HOST"), // e.g. '127.0.0.1' // Set Host to 'cloudsql' when deploying to App Engine Flexible environment Username = Environment.GetEnvironmentVariable("DB_USER"), // e.g. 'my-db-user' Password = Environment.GetEnvironmentVariable("DB_PASS"), // e.g. 'my-db-password' Database = Environment.GetEnvironmentVariable("DB_NAME"), // e.g. 'my-database' // The Cloud SQL proxy provides encryption between the proxy and instance. SslMode = SslMode.Disable, }; connectionString.Pooling = true; // Specify additional properties here. return connectionString; } } }
Ruby
如要查看網頁應用程式中的程式碼片段,請參閱 GitHub 上的 README。
tcp: &tcp adapter: postgresql # Configure additional properties here. # Note: Saving credentials in environment variables is convenient, but not # secure - consider a more secure solution such as # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help # keep secrets safe. username: <%= ENV["DB_USER"] %> # e.g. "my-database-user" password: <%= ENV["DB_PASS"] %> # e.g. "my-database-password" database: <%= ENV.fetch("DB_NAME") { "vote_development" } %> host: <%= ENV.fetch("INSTANCE_HOST") { "127.0.0.1" }%> # '172.17.0.1' if deployed to GAE Flex port: <%= ENV.fetch("DB_PORT") { 5432 }%>
PHP
如要查看網頁應用程式中的程式碼片段,請參閱 GitHub 上的 README。
namespace Google\Cloud\Samples\CloudSQL\Postgres; use PDO; use PDOException; use RuntimeException; use TypeError; class DatabaseTcp { public static function initTcpDatabaseConnection(): PDO { try { // Note: Saving credentials in environment variables is convenient, but not // secure - consider a more secure solution such as // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help // keep secrets safe. $username = getenv('DB_USER'); // e.g. 'your_db_user' $password = getenv('DB_PASS'); // e.g. 'your_db_password' $dbName = getenv('DB_NAME'); // e.g. 'your_db_name' $instanceHost = getenv('INSTANCE_HOST'); // e.g. '127.0.0.1' ('172.17.0.1' for GAE Flex) // Connect using TCP $dsn = sprintf('pgsql:dbname=%s;host=%s', $dbName, $instanceHost); // Connect to the database $conn = new PDO( $dsn, $username, $password, # ... ); } catch (TypeError $e) { throw new RuntimeException( sprintf( 'Invalid or missing configuration! Make sure you have set ' . '$username, $password, $dbName, and $instanceHost (for TCP mode). ' . 'The PHP error was %s', $e->getMessage() ), $e->getCode(), $e ); } catch (PDOException $e) { throw new RuntimeException( sprintf( 'Could not connect to the Cloud SQL Database. Check that ' . 'your username and password are correct, that the Cloud SQL ' . 'proxy is running, and that the database exists and is ready ' . 'for use. For more assistance, refer to %s. The PDO error was %s', 'https://cloud.google.com/sql/docs/postgres/connect-external-app', $e->getMessage() ), $e->getCode(), $e ); } return $conn; } }
透過 Unix 通訊端連線
Python
如要查看網頁應用程式中的程式碼片段,請參閱 GitHub 上的 README。
import os import sqlalchemy def connect_unix_socket() -> sqlalchemy.engine.base.Engine: """Initializes a Unix socket connection pool for a Cloud SQL instance of Postgres.""" # Note: Saving credentials in environment variables is convenient, but not # secure - consider a more secure solution such as # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help # keep secrets safe. db_user = os.environ["DB_USER"] # e.g. 'my-database-user' db_pass = os.environ["DB_PASS"] # e.g. 'my-database-password' db_name = os.environ["DB_NAME"] # e.g. 'my-database' unix_socket_path = os.environ[ "INSTANCE_UNIX_SOCKET" ] # e.g. '/cloudsql/project:region:instance' pool = sqlalchemy.create_engine( # Equivalent URL: # postgresql+pg8000://<db_user>:<db_pass>@/<db_name> # ?unix_sock=<INSTANCE_UNIX_SOCKET>/.s.PGSQL.5432 # Note: Some drivers require the `unix_sock` query parameter to use a different key. # For example, 'psycopg2' uses the path set to `host` in order to connect successfully. sqlalchemy.engine.url.URL.create( drivername="postgresql+pg8000", username=db_user, password=db_pass, database=db_name, query={"unix_sock": f"{unix_socket_path}/.s.PGSQL.5432"}, ), # ... ) return pool
Java
如要查看網頁應用程式中的程式碼片段,請參閱 GitHub 上的 README。
import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import javax.sql.DataSource; public class ConnectorConnectionPoolFactory extends ConnectionPoolFactory { // Note: Saving credentials in environment variables is convenient, but not // secure - consider a more secure solution such as // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help // keep secrets safe. private static final String INSTANCE_CONNECTION_NAME = System.getenv("INSTANCE_CONNECTION_NAME"); private static final String INSTANCE_UNIX_SOCKET = System.getenv("INSTANCE_UNIX_SOCKET"); private static final String DB_USER = System.getenv("DB_USER"); private static final String DB_PASS = System.getenv("DB_PASS"); private static final String DB_NAME = System.getenv("DB_NAME"); public static DataSource createConnectionPool() { // The configuration object specifies behaviors for the connection pool. HikariConfig config = new HikariConfig(); // The following URL is equivalent to setting the config options below: // jdbc:postgresql:///<DB_NAME>?cloudSqlInstance=<INSTANCE_CONNECTION_NAME>& // socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=<DB_USER>&password=<DB_PASS> // See the link below for more info on building a JDBC URL for the Cloud SQL JDBC Socket Factory // https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory#creating-the-jdbc-url // Configure which instance and what database user to connect with. config.setJdbcUrl(String.format("jdbc:postgresql:///%s", DB_NAME)); config.setUsername(DB_USER); // e.g. "root", _postgres" config.setPassword(DB_PASS); // e.g. "my-password" config.addDataSourceProperty("socketFactory", "com.google.cloud.sql.postgres.SocketFactory"); config.addDataSourceProperty("cloudSqlInstance", INSTANCE_CONNECTION_NAME); // Unix sockets are not natively supported in Java, so it is necessary to use the Cloud SQL // Java Connector to connect. When setting INSTANCE_UNIX_SOCKET, the connector will // call an external package that will enable Unix socket connections. // Note: For Java users, the Cloud SQL Java Connector can provide authenticated connections // which is usually preferable to using the Cloud SQL Proxy with Unix sockets. // See https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory for details. if (INSTANCE_UNIX_SOCKET != null) { config.addDataSourceProperty("unixSocketPath", INSTANCE_UNIX_SOCKET); } // cloudSqlRefreshStrategy set to "lazy" is used to perform a // refresh when needed, rather than on a scheduled interval. // This is recommended for serverless environments to // avoid background refreshes from throttling CPU. config.addDataSourceProperty("cloudSqlRefreshStrategy", "lazy"); // ... Specify additional connection properties here. // ... // Initialize the connection pool using the configuration object. return new HikariDataSource(config); } }
Node.js
如要查看網頁應用程式中的程式碼片段,請參閱 GitHub 上的 README。
const Knex = require('knex'); // createUnixSocketPool initializes a Unix socket connection pool for // a Cloud SQL instance of Postgres. const createUnixSocketPool = async config => { // Note: Saving credentials in environment variables is convenient, but not // secure - consider a more secure solution such as // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help // keep secrets safe. return Knex({ client: 'pg', connection: { user: process.env.DB_USER, // e.g. 'my-user' password: process.env.DB_PASS, // e.g. 'my-user-password' database: process.env.DB_NAME, // e.g. 'my-database' host: process.env.INSTANCE_UNIX_SOCKET, // e.g. '/cloudsql/project:region:instance' }, // ... Specify additional properties here. ...config, }); };
C#
如要查看網頁應用程式中的程式碼片段,請參閱 GitHub 上的 README。
using Npgsql; using System; namespace CloudSql { public class PostgreSqlUnix { public static NpgsqlConnectionStringBuilder NewPostgreSqlUnixSocketConnectionString() { // Equivalent connection string: // "Server=<INSTANCE_UNIX_SOCKET>;Uid=<DB_USER>;Pwd=<DB_PASS>;Database=<DB_NAME>" var connectionString = new NpgsqlConnectionStringBuilder() { // The Cloud SQL proxy provides encryption between the proxy and instance. SslMode = SslMode.Disable, // Note: Saving credentials in environment variables is convenient, but not // secure - consider a more secure solution such as // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help // keep secrets safe. Host = Environment.GetEnvironmentVariable("INSTANCE_UNIX_SOCKET"), // e.g. '/cloudsql/project:region:instance' Username = Environment.GetEnvironmentVariable("DB_USER"), // e.g. 'my-db-user Password = Environment.GetEnvironmentVariable("DB_PASS"), // e.g. 'my-db-password' Database = Environment.GetEnvironmentVariable("DB_NAME"), // e.g. 'my-database' }; connectionString.Pooling = true; // Specify additional properties here. return connectionString; } } }
Go
如要查看網頁應用程式中的程式碼片段,請參閱 GitHub 上的 README。
package cloudsql import ( "database/sql" "fmt" "log" "os" // Note: If connecting using the App Engine Flex Go runtime, use // "github.com/jackc/pgx/stdlib" instead, since v5 requires // Go modules which are not supported by App Engine Flex. _ "github.com/jackc/pgx/v5/stdlib" ) // connectUnixSocket initializes a Unix socket connection pool for // a Cloud SQL instance of Postgres. func connectUnixSocket() (*sql.DB, error) { mustGetenv := func(k string) string { v := os.Getenv(k) if v == "" { log.Fatalf("Fatal Error in connect_unix.go: %s environment variable not set.\n", k) } return v } // Note: Saving credentials in environment variables is convenient, but not // secure - consider a more secure solution such as // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help // keep secrets safe. var ( dbUser = mustGetenv("DB_USER") // e.g. 'my-db-user' dbPwd = mustGetenv("DB_PASS") // e.g. 'my-db-password' unixSocketPath = mustGetenv("INSTANCE_UNIX_SOCKET") // e.g. '/cloudsql/project:region:instance' dbName = mustGetenv("DB_NAME") // e.g. 'my-database' ) dbURI := fmt.Sprintf("user=%s password=%s database=%s host=%s", dbUser, dbPwd, dbName, unixSocketPath) // dbPool is the pool of database connections. dbPool, err := sql.Open("pgx", dbURI) if err != nil { return nil, fmt.Errorf("sql.Open: %w", err) } // ... return dbPool, nil }
Ruby
如要查看網頁應用程式中的程式碼片段,請參閱 GitHub 上的 README。
unix: &unix adapter: postgresql # Configure additional properties here. # Note: Saving credentials in environment variables is convenient, but not # secure - consider a more secure solution such as # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help # keep secrets safe. username: <%= ENV["DB_USER"] %> # e.g. "my-database-user" password: <%= ENV["DB_PASS"] %> # e.g. "my-database-password" database: <%= ENV.fetch("DB_NAME") { "vote_development" } %> # Specify the Unix socket path as host host: "<%= ENV["INSTANCE_UNIX_SOCKET"] %>"
PHP
如要查看網頁應用程式中的程式碼片段,請參閱 GitHub 上的 README。
namespace Google\Cloud\Samples\CloudSQL\Postgres; use PDO; use PDOException; use RuntimeException; use TypeError; class DatabaseUnix { public static function initUnixDatabaseConnection(): PDO { try { // Note: Saving credentials in environment variables is convenient, but not // secure - consider a more secure solution such as // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help // keep secrets safe. $username = getenv('DB_USER'); // e.g. 'your_db_user' $password = getenv('DB_PASS'); // e.g. 'your_db_password' $dbName = getenv('DB_NAME'); // e.g. 'your_db_name' $instanceUnixSocket = getenv('INSTANCE_UNIX_SOCKET'); // e.g. '/cloudsql/project:region:instance' // Connect using UNIX sockets $dsn = sprintf( 'pgsql:dbname=%s;host=%s', $dbName, $instanceUnixSocket ); // Connect to the database. $conn = new PDO( $dsn, $username, $password, # ... ); } catch (TypeError $e) { throw new RuntimeException( sprintf( 'Invalid or missing configuration! Make sure you have set ' . '$username, $password, $dbName, ' . 'and $instanceUnixSocket (for UNIX socket mode). ' . 'The PHP error was %s', $e->getMessage() ), (int) $e->getCode(), $e ); } catch (PDOException $e) { throw new RuntimeException( sprintf( 'Could not connect to the Cloud SQL Database. Check that ' . 'your username and password are correct, that the Cloud SQL ' . 'proxy is running, and that the database exists and is ready ' . 'for use. For more assistance, refer to %s. The PDO error was %s', 'https://cloud.google.com/sql/docs/postgres/connect-external-app', $e->getMessage() ), (int) $e->getCode(), $e ); } return $conn; } }
開啟及關閉連線
您使用連線集區時,必須正確開啟和關閉連線,以確保連線在您每次使用完畢後都會回到集區。未回到集區的連線 (或稱「外洩」連線) 將無法重複使用,因而造成資源浪費,也可能導致應用程式效能瓶頸。
Python
# Preparing a statement before hand can help protect against injections. stmt = sqlalchemy.text( "INSERT INTO votes (time_cast, candidate) VALUES (:time_cast, :candidate)" ) try: # Using a with statement ensures that the connection is always released # back into the pool at the end of statement (even if an error occurs) with db.connect() as conn: conn.execute(stmt, parameters={"time_cast": time_cast, "candidate": team}) conn.commit() except Exception as e: # If something goes wrong, handle the error in this section. This might # involve retrying or adjusting parameters depending on the situation. # ...
Java
// Using a try-with-resources statement ensures that the connection is always released back // into the pool at the end of the statement (even if an error occurs) try (Connection conn = pool.getConnection()) { // PreparedStatements can be more efficient and project against injections. String stmt = "INSERT INTO votes (time_cast, candidate) VALUES (?, ?);"; try (PreparedStatement voteStmt = conn.prepareStatement(stmt);) { voteStmt.setTimestamp(1, now); voteStmt.setString(2, team); // Finally, execute the statement. If it fails, an error will be thrown. voteStmt.execute(); } } catch (SQLException ex) { // If something goes wrong, handle the error in this section. This might involve retrying or // adjusting parameters depending on the situation. // ... }
Node.js
/** * Insert a vote record into the database. * * @param {object} pool The Knex connection object. * @param {object} vote The vote record to insert. * @returns {Promise} */ const insertVote = async (pool, vote) => { try { return await pool('votes').insert(vote); } catch (err) { throw Error(err); } };
C#
using Npgsql; using System; namespace CloudSql { public class PostgreSqlTcp { public static NpgsqlConnectionStringBuilder NewPostgreSqlTCPConnectionString() { // Equivalent connection string: // "Uid=<DB_USER>;Pwd=<DB_PASS>;Host=<INSTANCE_HOST>;Database=<DB_NAME>;" var connectionString = new NpgsqlConnectionStringBuilder() { // Note: Saving credentials in environment variables is convenient, but not // secure - consider a more secure solution such as // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help // keep secrets safe. Host = Environment.GetEnvironmentVariable("INSTANCE_HOST"), // e.g. '127.0.0.1' // Set Host to 'cloudsql' when deploying to App Engine Flexible environment Username = Environment.GetEnvironmentVariable("DB_USER"), // e.g. 'my-db-user' Password = Environment.GetEnvironmentVariable("DB_PASS"), // e.g. 'my-db-password' Database = Environment.GetEnvironmentVariable("DB_NAME"), // e.g. 'my-database' // The Cloud SQL proxy provides encryption between the proxy and instance. SslMode = SslMode.Disable, }; connectionString.Pooling = true; // Specify additional properties here. return connectionString; } } }
Go
insertVote := "INSERT INTO votes(candidate, created_at) VALUES($1, NOW())" _, err := db.Exec(insertVote, team)
Ruby
@vote = Vote.new candidate: candidate # ActiveRecord creates and executes your SQL and automatically # handles the opening and closing of the database connection. if @vote.save render json: "Vote successfully cast for \"#{@vote.candidate}\" at #{@vote.time_cast} PST!" else render json: @vote.errors, status: :unprocessable_entity end
PHP
// Use prepared statements to guard against SQL injection. $sql = 'INSERT INTO votes (time_cast, candidate) VALUES (NOW(), :voteValue)'; try { $statement = $conn->prepare($sql); $statement->bindParam('voteValue', $value); $res = $statement->execute(); } catch (PDOException $e) { throw new RuntimeException( 'Could not insert vote into database. The PDO exception was ' . $e->getMessage(), $e->getCode(), $e ); }
連線計數
每個資料庫連線都會使用用戶端和伺服器端資源。此外,Cloud SQL 也會強制執行整體連線限制,不得超過。建立及使用較少的連線可減少負擔,並協助您維持在連線限制內。
Python
# Pool size is the maximum number of permanent connections to keep. pool_size=5, # Temporarily exceeds the set pool_size if no connections are available. max_overflow=2, # The total number of concurrent connections for your application will be # a total of pool_size and max_overflow.
Java
// maximumPoolSize limits the total number of concurrent connections this pool will keep. Ideal // values for this setting are highly variable on app design, infrastructure, and database. config.setMaximumPoolSize(5); // minimumIdle is the minimum number of idle connections Hikari maintains in the pool. // Additional connections will be established to meet this value unless the pool is full. config.setMinimumIdle(5);
Node.js
// 'max' limits the total number of concurrent connections this pool will keep. Ideal // values for this setting are highly variable on app design, infrastructure, and database. config.pool.max = 5; // 'min' is the minimum number of idle connections Knex maintains in the pool. // Additional connections will be established to meet this value unless the pool is full. config.pool.min = 5;
C#
// MaxPoolSize sets maximum number of connections allowed in the pool. connectionString.MaxPoolSize = 5; // MinPoolSize sets the minimum number of connections in the pool. connectionString.MinPoolSize = 0;
Go
// Set maximum number of connections in idle connection pool. db.SetMaxIdleConns(5) // Set maximum number of open connections to the database. db.SetMaxOpenConns(7)
Ruby
# 'pool' is the maximum number of permanent connections to keep. pool: 5
PHP
PDO 目前未提供任何可設定連線限制的功能。
指數輪詢
如果您的應用程式嘗試連線至資料庫卻未成功,原因可能是資料庫暫時無法提供服務。在這種情況下,重複傳送連線要求會浪費資源。建議您先等待,再傳送其他連線要求,讓資料庫恢復存取權。使用指數輪詢或其他延遲機制,即可達成這個目標。
只有在首次連線或首次從集區擷取連線時,重試才有意義。如果在交易期間發生錯誤,應用程式必須重試,且必須從交易開始時重試。因此,即使集區設定正確,如果連線中斷,應用程式仍可能會看到錯誤。
Python
# SQLAlchemy automatically uses delays between failed connection attempts, # but provides no arguments for configuration.
Java
// Hikari automatically delays between failed connection attempts, eventually reaching a // maximum delay of `connectionTimeout / 2` between attempts.
Node.js
// 'knex' uses a built-in retry strategy which does not implement backoff. // 'createRetryIntervalMillis' is how long to idle after failed connection creation before trying again config.pool.createRetryIntervalMillis = 200; // 0.2 seconds
C#
Policy .Handle<NpgsqlException>() .WaitAndRetry(new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(5) }) .Execute(() => connection.Open());
Go
database/sql 套件目前未提供任何可設定指數輪詢的功能。
Ruby
# ActiveRecord automatically uses delays between failed connection attempts, # but provides no arguments for configuration.
PHP
PDO 目前未提供任何可設定指數輪詢的功能。
連線逾時
嘗試連線失敗的原因有很多,例如網路通訊的不穩定,以及資料庫可能暫時無法回應。請確保應用程式能妥善處理連線中斷或連線失敗的情況。
Python
# 'pool_timeout' is the maximum number of seconds to wait when retrieving a # new connection from the pool. After the specified amount of time, an # exception will be thrown. pool_timeout=30, # 30 seconds
Java
// setConnectionTimeout is the maximum number of milliseconds to wait for a connection checkout. // Any attempt to retrieve a connection from this pool that exceeds the set limit will throw an // SQLException. config.setConnectionTimeout(10000); // 10 seconds // idleTimeout is the maximum amount of time a connection can sit in the pool. Connections that // sit idle for this many milliseconds are retried if minimumIdle is exceeded. config.setIdleTimeout(600000); // 10 minutes
Node.js
// 'acquireTimeoutMillis' is the number of milliseconds before a timeout occurs when acquiring a // connection from the pool. This is slightly different from connectionTimeout, because acquiring // a pool connection does not always involve making a new connection, and may include multiple retries. // when making a connection config.pool.acquireTimeoutMillis = 60000; // 60 seconds // 'createTimeoutMillis` is the maximum number of milliseconds to wait trying to establish an // initial connection before retrying. // After acquireTimeoutMillis has passed, a timeout exception will be thrown. config.pool.createTimeoutMillis = 30000; // 30 seconds // 'idleTimeoutMillis' is the number of milliseconds a connection must sit idle in the pool // and not be checked out before it is automatically closed. config.pool.idleTimeoutMillis = 600000; // 10 minutes
C#
// Timeout sets the time to wait (in seconds) while // trying to establish a connection before terminating the attempt. connectionString.Timeout = 15;
Go
database/sql 套件目前未提供任何可設定連線逾時的功能。逾時是在驅動程式層級設定。
Ruby
# 'timeout' is the maximum number of seconds to wait when retrieving a # new connection from the pool. After the specified amount of time, an # ActiveRecord::ConnectionTimeoutError will be raised. timeout: 5000
PHP
// Here we set the connection timeout to five seconds and ask PDO to // throw an exception if any errors occur. [ PDO::ATTR_TIMEOUT => 5, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, ]
連線持續時間
限制連線效期可避免捨棄的連線越積越多。您可以使用連線集區來限制您的連線效期。
Python
# 'pool_recycle' is the maximum number of seconds a connection can persist. # Connections that live longer than the specified amount of time will be # re-established pool_recycle=1800, # 30 minutes
Java
// maxLifetime is the maximum possible lifetime of a connection in the pool. Connections that // live longer than this many milliseconds will be closed and reestablished between uses. This // value should be several minutes shorter than the database's timeout value to avoid unexpected // terminations. config.setMaxLifetime(1800000); // 30 minutes
Node.js
「knex」Node.js 程式庫目前未提供任何可控制連線持續時間的功能。
C#
// ConnectionIdleLifetime sets the time (in seconds) to wait before // closing idle connections in the pool if the count of all // connections exceeds MinPoolSize. connectionString.ConnectionIdleLifetime = 300;
Go
// Set Maximum time (in seconds) that a connection can remain open. db.SetConnMaxLifetime(1800 * time.Second)
Ruby
ActiveRecord 目前未提供任何可控制連線持續時間的功能。
PHP
PDO 目前未提供任何可控制連線持續時間的功能。
查看完整的應用程式
如要查看完整的應用程式,請按一下下方連結。
Python
查看以 Python 程式設計語言撰寫的完整應用程式。
Java
查看以 Java 程式設計語言撰寫的完整應用程式。
Node.js
查看以 Node.js 程式設計語言撰寫的完整應用程式。
C#
查看以 C# 程式設計語言撰寫的完整應用程式。
Go
查看以 Go 程式設計語言撰寫的完整應用程式。
Ruby
查看以 Ruby 程式設計語言撰寫的完整應用程式。
PHP
查看以 PHP 程式設計語言撰寫的完整應用程式。