|
@@ -15,84 +15,89 @@ class U8DatabaseServerService extends Service
|
|
|
public function __construct($loginUser = [])
|
|
public function __construct($loginUser = [])
|
|
|
{
|
|
{
|
|
|
$this->database = $loginUser['zt_database'] ?? "";
|
|
$this->database = $loginUser['zt_database'] ?? "";
|
|
|
- $this->connName = 'sqlsrv_main_' . uniqid();
|
|
|
|
|
|
|
+ $this->connName = 'sqlsrv_' . $this->database . '_' . uniqid();
|
|
|
$this->createConnection();
|
|
$this->createConnection();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private function createConnection()
|
|
private function createConnection()
|
|
|
{
|
|
{
|
|
|
- // 主数据库连接
|
|
|
|
|
$mainConnName = $this->connName;
|
|
$mainConnName = $this->connName;
|
|
|
|
|
+
|
|
|
|
|
+ // 创建连接
|
|
|
$mainConfig = [
|
|
$mainConfig = [
|
|
|
- 'driver' => 'sqlsrv',
|
|
|
|
|
- 'host' => env('SQLSRV_HOST'),
|
|
|
|
|
- 'port' => env('SQLSRV_PORT'),
|
|
|
|
|
|
|
+ 'driver' => 'sqlsrv',
|
|
|
|
|
+ 'host' => env('SQLSRV_HOST'),
|
|
|
|
|
+ 'port' => env('SQLSRV_PORT'),
|
|
|
'database' => $this->database,
|
|
'database' => $this->database,
|
|
|
'username' => env('SQLSRV_USERNAME'),
|
|
'username' => env('SQLSRV_USERNAME'),
|
|
|
'password' => env('SQLSRV_PASSWORD'),
|
|
'password' => env('SQLSRV_PASSWORD'),
|
|
|
- 'options' => [
|
|
|
|
|
- \PDO::SQLSRV_ATTR_QUERY_TIMEOUT => 30, // SQL Server专用超时
|
|
|
|
|
|
|
+ 'options' => [
|
|
|
|
|
+ \PDO::SQLSRV_ATTR_QUERY_TIMEOUT => 15, // 减少超时
|
|
|
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
|
|
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
|
|
|
],
|
|
],
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
|
|
+ // 配置注入
|
|
|
Config::set("database.connections.{$mainConnName}", $mainConfig);
|
|
Config::set("database.connections.{$mainConnName}", $mainConfig);
|
|
|
|
|
+
|
|
|
|
|
+ // 连接
|
|
|
$this->db = DB::connection($mainConnName);
|
|
$this->db = DB::connection($mainConnName);
|
|
|
|
|
|
|
|
- // 测试连接有效性
|
|
|
|
|
|
|
+ // 测试
|
|
|
$this->validateConnection($this->db);
|
|
$this->validateConnection($this->db);
|
|
|
|
|
+
|
|
|
|
|
+ // 如果失败,立即清理,避免残留连接名
|
|
|
|
|
+ if ($this->error) {
|
|
|
|
|
+ $this->safeDisconnect($this->db, $mainConnName);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private function validateConnection($connection)
|
|
private function validateConnection($connection)
|
|
|
{
|
|
{
|
|
|
try {
|
|
try {
|
|
|
- $pdo = $connection->getPdo();
|
|
|
|
|
|
|
+ $pdo = $connection->getPdo();
|
|
|
$stmt = $pdo->prepare("SELECT 1 AS connection_test");
|
|
$stmt = $pdo->prepare("SELECT 1 AS connection_test");
|
|
|
$stmt->execute();
|
|
$stmt->execute();
|
|
|
- $result = $stmt->fetch(\PDO::FETCH_ASSOC);
|
|
|
|
|
-
|
|
|
|
|
- if (empty($result) || $result['connection_test'] != 1) {
|
|
|
|
|
- $this->error = "数据库连接失败";
|
|
|
|
|
- }
|
|
|
|
|
} catch (\Throwable $e) {
|
|
} catch (\Throwable $e) {
|
|
|
$this->error = "数据库连接验证失败: " . $e->getMessage();
|
|
$this->error = "数据库连接验证失败: " . $e->getMessage();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public function __destruct()
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 手动关闭连接(定时任务必须调用)
|
|
|
|
|
+ */
|
|
|
|
|
+ public function close()
|
|
|
{
|
|
{
|
|
|
- // 主动关闭连接
|
|
|
|
|
- $this->safeDisconnect($this->db);
|
|
|
|
|
|
|
+ $this->safeDisconnect($this->db, $this->connName);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private function safeDisconnect(&$connection)
|
|
|
|
|
|
|
+ private function safeDisconnect(&$connection, $name)
|
|
|
{
|
|
{
|
|
|
try {
|
|
try {
|
|
|
if ($connection instanceof \Illuminate\Database\Connection) {
|
|
if ($connection instanceof \Illuminate\Database\Connection) {
|
|
|
- // 物理断开连接
|
|
|
|
|
- $connection->disconnect();
|
|
|
|
|
|
|
|
|
|
- // 获取连接名称
|
|
|
|
|
- $name = $connection->getName();
|
|
|
|
|
|
|
+ // 断开物理连接
|
|
|
|
|
+ $connection->disconnect();
|
|
|
|
|
|
|
|
- // 清除 Laravel 内置连接池
|
|
|
|
|
|
|
+ // 清除 Laravel 连接池
|
|
|
DB::purge($name);
|
|
DB::purge($name);
|
|
|
|
|
|
|
|
- // 移除动态配置
|
|
|
|
|
|
|
+ // 移除配置
|
|
|
Config::offsetUnset("database.connections.{$name}");
|
|
Config::offsetUnset("database.connections.{$name}");
|
|
|
|
|
|
|
|
- // 清除连接引用
|
|
|
|
|
|
|
+ // 引用置空
|
|
|
$connection = null;
|
|
$connection = null;
|
|
|
-
|
|
|
|
|
-// Log::info("动作", [
|
|
|
|
|
-// 'param' => "执行了析构",
|
|
|
|
|
-// ]);
|
|
|
|
|
}
|
|
}
|
|
|
} catch (\Throwable $e) {
|
|
} catch (\Throwable $e) {
|
|
|
- // 静默处理断开错误
|
|
|
|
|
-// Log::info("错误", [
|
|
|
|
|
-// 'param' => $e->getMessage(),
|
|
|
|
|
-// ]);
|
|
|
|
|
|
|
+ // 忽略
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 阻止依赖 __destruct
|
|
|
|
|
+ */
|
|
|
|
|
+ public function __destruct()
|
|
|
|
|
+ {
|
|
|
|
|
+ // 不做任何事,避免不确定行为
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|