USEGEAR

导航

restful 服务器一个问题,看ChatGPT的威力 (续2)

实际上Pascal是一个非常优美的语言。只是仁者见仁智者见智。

我们一直埋怨,而不是埋怨自己。说到底:功力不够。想短平快,功底又不够,这就是挑战。

datasnap很复杂,但是又很简单。写了够小的破restful服务程序,动不动出问题。

在多次交流中,你会不断理解和提高。

 

 

 

# Delphi + REST + 多线程数据库连接规范清单

## 🎯 目标

短连接、线程安全、资源无泄漏、TCP 不挂起

---

## 1️⃣ 连接创建原则

- 所有方法中**禁止使用组件字段** `FDConnection1` 直接执行查询
- **统一使用局部变量**:`LConn: TFDConnection`
- 建议封装工具函数统一创建连接:`CreateLocalFDConnectionFromTemplate`

---

## 2️⃣ 安全连接参数设置

```pascal
LConn := TFDConnection.Create(nil);
LConn.LoginPrompt := False;
LConn.Params.Assign(FDConnection1.Params);
LConn.Params.Pooled := False;
LConn.Connected := True;
```

---

## 3️⃣ 查询/操作对象规则

```pascal
LQuery := TFDQuery.Create(nil);
LQuery.Connection := LConn;
```

不要使用设计时组件字段,如 `FDQuery1`, `FDCommand1`。

---

## 4️⃣ 释放规则(必须使用 try..finally)

```pascal
try
  // 操作
finally
  if LConn.Connected then LConn.Close;
  LConn.Free;
end;
```

如使用账套切换:

```pascal
FDManager.CloseConnectionDef(LConn.ConnectionDefName);
```

---

## 5️⃣ 多线程场景特殊规则

- 所有数据库对象(连接、查询)必须是**局部变量**
- 禁止在线程中访问 `FDConnection1` 组件字段
- 使用 `TTask`, `TThread`, `TEvent`, `TInterlocked` 做线程同步
- 使用 `PostLog` 记录连接耗时及释放日志

---

## 6️⃣ 调试建议

```pascal
FDManager.Tracing := True;
FDManager.TraceFileName := 'FDTrace.log';
```

查询 SQL Server 当前连接:

```sql
SELECT * FROM sys.dm_exec_connections WHERE session_id <> @@SPID;
```

查看连接数:

```pascal
ShowMessage(IntToStr(FDManager.ActiveConnections));
```

---

## 7️⃣ REST 方法封装建议

```pascal
function GetFDJSONDatasets(aSqlExpr: string): TFDJSONDatasets;
var
  LConn: TFDConnection;
  LQuery: TFDQuery;
begin
  LConn := CreateLocalFDConnectionFromTemplate(FDConnection1);
  try
    LQuery := TFDQuery.Create(nil);
    try
      LQuery.Connection := LConn;
      LQuery.SQL.Text := aSqlExpr;
      LQuery.Open;
      Result := TFDJSONDataSetsWriter.WriteDataSets([LQuery]);
    finally
      LQuery.Free;
    end;
  finally
    if LConn.Connected then LConn.Close;
    LConn.Free;
  end;
end;
```

---

## 推荐封装函数

```pascal
function CreateLocalFDConnectionFromTemplate(BaseConn: TFDConnection): TFDConnection;
begin
  Result := TFDConnection.Create(nil);
  Result.LoginPrompt := False;
  Result.Params.Assign(BaseConn.Params);
  Result.Params.Pooled := False;
  Result.Connected := True;
end;
```

---

## ✅ 结语

> 短连接 REST 服务的本质是:**每次来一个连接,用完立即释放,绝不残留。**

 

 

 

 

posted on 2025-04-02 19:02  USEGEAR  阅读(30)  评论(0)    收藏  举报