# 事务与错误处理
**本文档引用的文件**
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp)
- [IOManager.h](file://h/IOManager.h)
- [upg_geo_filetrans_log.txt](file://LOG/upg_geo_filetrans_log.txt)
- [msado15.tlh](file://Release/msado15.tlh)
- [msado15.tli](file://Release/msado15.tli)
- [TdManager.cpp](file://cpp/Managers/TdManager.cpp)
- [Zmodem.cpp](file://cpp/Tools/Zmodem.cpp)
- [FileTransfer.cpp](file://cpp/Tools/FileTransfer.cpp)
## 目录
1. [事务管理机制](#事务管理机制)
2. [错误处理机制](#错误处理机制)
3. [日志记录与诊断流程](#日志记录与诊断流程)
4. [常见数据库错误代码与恢复建议](#常见数据库错误代码与恢复建议)
## 事务管理机制
`CIOManager` 类实现了基于 ADO 数据库连接的事务管理机制,用于确保数据操作的原子性、一致性和完整性。该机制主要应用于批量数据导出和导入操作,通过 `BeginTrans`、`CommitTrans` 和 `RollbackTrans` 方法来控制事务的生命周期。
在数据导出操作中,`Export` 方法首先创建一个新的数据库连接,并调用 `BeginTrans` 开始事务。随后,系统将项目、测区、测点等数据分批写入新数据库。如果所有操作均成功完成,则调用 `CommitTrans` 提交事务,使更改永久生效;若在操作过程中发生异常,则通过 `catch` 块捕获 `_com_error` 异常,并调用 `RollbackTrans` 回滚事务,撤销所有已执行的更改,从而保证数据的一致性。
```mermaid
sequenceDiagram
participant 用户 as 用户界面
participant IOManager as CIOManager
participant 数据库 as 目标数据库
用户->>IOManager : 启动导出操作
IOManager->>数据库 : BeginTrans()
IOManager->>数据库 : 写入项目数据
IOManager->>数据库 : 写入测区数据
IOManager->>数据库 : 写入测点数据
alt 操作成功
IOManager->>数据库 : CommitTrans()
IOManager-->>用户 : 导出成功
else 操作失败
IOManager->>数据库 : RollbackTrans()
IOManager-->>用户 : 导出失败,已回滚
end
```
**Diagram sources**
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L50-L98)
**Section sources**
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L35-L98)
- [IOManager.h](file://h/IOManager.h#L20)
## 错误处理机制
系统采用结构化的异常处理机制来应对数据库连接失败、SQL 执行错误和文件 I/O 异常等情况。核心错误处理逻辑基于 COM 组件的 `_com_error` 异常捕获机制,结合 ADO 错误对象进行详细诊断。
在数据库操作中,任何 ADO 方法调用失败都会抛出 `_com_error` 异常。系统通过 `try-catch` 块捕获这些异常,并根据错误信息采取相应措施。例如,在 `Import` 方法中,如果数据库连接失败或 SQL 查询出错,系统会回滚当前事务并返回错误代码。此外,`TdManager` 类中的 `ExecuteSql` 方法也实现了类似的事务控制和异常处理逻辑,确保复杂业务流程的数据完整性。
对于文件 I/O 操作,`Zmodem.cpp` 文件中的 `ReceiveSingleFile` 函数定义了多种错误状态码(如 `ZERROR`、`TIMEOUT`),并在发生错误时记录日志并终止传输。`FileTransfer.cpp` 提供了 `error` 和 `status` 函数用于输出错误和状态信息,辅助调试和问题定位。
```mermaid
flowchart TD
Start([开始数据库操作]) --> Try["try {
执行数据库操作
}"]
Try --> Catch["catch (_com_error e) {"]
Catch --> Rollback["调用 RollbackTrans()"]
Rollback --> Log["记录错误信息"]
Log --> Return["返回错误代码"]
Try --> Success["操作成功"]
Success --> Commit["调用 CommitTrans()"]
Commit --> End([结束])
```
**Diagram sources**
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L101-L204)
- [TdManager.cpp](file://cpp/Managers/TdManager.cpp#L6818-L6831)
- [Zmodem.cpp](file://cpp/Tools/Zmodem.cpp#L219-L749)
**Section sources**
- [IOManager.cpp](file://cpp/Managers/IOManager.cpp#L101-L204)
- [TdManager.cpp](file://cpp/Managers/TdManager.cpp#L6818-L6831)
- [Zmodem.cpp](file://cpp/Tools/Zmodem.cpp#L219-L749)
- [FileTransfer.cpp](file://cpp/Tools/FileTransfer.cpp#L28-L46)
## 日志记录与诊断流程
系统通过日志文件 `upg_geo_filetrans_log.txt` 记录网络请求失败等关键错误信息。当系统尝试访问更新服务器 `update.geomative.com` 时,若域名解析失败,会将详细的错误信息(包括时间戳、错误描述和 URL)写入日志文件。这种机制有助于诊断网络连接问题和服务器不可达情况。
日志条目格式包含时间戳、线程 ID、错误级别和具体错误消息,便于追踪问题发生的时间和上下文。例如,日志中记录了两次 `curl_perform failed!` 错误,均因无法解析主机名导致,这表明可能存在 DNS 配置问题或网络中断。
**Section sources**
- [upg_geo_filetrans_log.txt](file://LOG/upg_geo_filetrans_log.txt#L1-L3)
## 常见数据库错误代码与恢复建议
根据 ADO 错误代码定义,以下是常见数据库错误及其恢复建议:
| 错误代码 | 错误常量 | 描述 | 恢复建议 |
|---------|---------|------|--------|
| 3004 | adErrWriteFile | 写文件错误 | 检查磁盘空间和文件权限 |
| 3219 | adErrIllegalOperation | 非法操作 | 检查操作是否在正确状态下执行 |
| 3246 | adErrInTransaction | 正在事务中 | 确保事务正确提交或回滚 |
| 3704 | adErrObjectClosed | 对象已关闭 | 在使用前检查对象是否已打开 |
| 3705 | adErrObjectOpen | 对象已打开 | 确保对象在使用后正确关闭 |
| 3706 | adErrProviderNotFound | 未找到提供程序 | 检查数据库驱动安装 |
| 3709 | adErrInvalidConnection | 无效连接 | 重新建立数据库连接 |
| 3714 | adErrInvalidTransaction | 无效事务 | 检查事务状态并重新开始 |
当遇到数据库错误时,建议首先检查连接状态,然后根据具体错误代码采取相应措施。对于可恢复错误(如连接中断),可尝试重新连接并重试操作;对于不可恢复错误(如权限不足),需联系管理员解决。
**Section sources**
- [msado15.tlh](file://Release/msado15.tlh#L613-L654)
- [msado15.tli](file://Release/msado15.tli#L1976-L1992)