多线程编程的数据库注意事项

在多线程程序中使用数据库时,请注意以下注意事项。

  • 数据定义语言(DDL)

    许多数据库配置,管理和设置类型接口都是线程安全的。 线程安全的数据库操作包括: Create FileAdd MemberDelete FileRemove Member。 请参阅 CL Reference 或使用 Display Command (DSPCMD) 命令来确定命令是否是线程安全的。 该命令的联机帮助信息列出了适用于命令的线程安全的任何必要条件。

  • 数据库记录 I/O

    数据库在操作期间 (读,更新,插入或删除) 保护 I/O 操作。 在线程之间共享文件的打开实例时,必须序列化对 I/O 反馈区域和 I/O 缓冲区的访问以查看这些区域中的有效信息。 这些区域受应用程序控制,在数据库操作完成后,数据库无法保护它们。

    例如,读操作。 如果线程 1 正在执行读操作,并且线程 2 对同一打开实例执行任何 I/O 操作,那么线程 2 将等待线程 1 完成读操作。 线程 1 中读操作的结果将放在 I/O 缓冲区中。 当控制返回到线程 1 时,线程 2 将开始其 I/O 操作。 在不进行序列化的情况下,线程 2 可以先更改 I/O 缓冲区中的信息,然后线程 1 才能查看结果。

    如果线程不共享文件的打开实例,那么不需要序列化。

  • 分布式文件

    对与 DB2® Multisystem 一起使用的分布式数据库文件的访问以及对类型为 *SNA 的分布式数据管理 (DDM) 文件的访问不是线程安全的。 多线程作业拒绝访问这些类型的数据库文件。 由于系统间通信功能 (ICF) 文件和整个 "系统网络体系结构" (SNA) 层不是线程安全的,因此无法使这些文件类型成为线程安全的。 如果尝试打开其中一种文件类型,那么 CPF4380 消息 (Open attributes not valid in a multithreaded process) 发送到尝试打开文件的函数。

  • 触发器程序

    可以在多线程作业中触发触发器程序。 与在多线程作业中运行的任何其他代码一样,相同的线程安全限制也适用于触发器程序。 Add Physical File Trigger (ADDPFTRG) 命令上的参数允许指定触发器的线程安全状态以及在多线程作业中触发触发器时要执行的操作。

  • 格式选择器程序

    对于具有多种格式的逻辑文件,使用格式选择器程序不是线程安全的。 不应在多线程作业中使用格式选择器程序。

  • 存储过程

    DB2 结构化查询语言 (SQL) 存储过程支持为 SQL 应用程序提供了一种通过 SQL 语句定义和调用外部程序的方法。 可以在多线程作业中调用存储过程。 与在多线程作业中运行的任何其他代码相同的线程安全限制适用于存储过程。 与触发器程序不同,无法指定存储过程的线程安全状态以及在多线程作业中调用存储过程时要执行的操作。

  • SQL 语句

    使用 DDL SQL 语句可能不是线程安全的。 数据操作语言 (DML) 语句是线程安全的。

  • SQL服务器方式

    使用 SQL 的服务器方式是使用多线程应用程序访问数据库的首选方法。 作业可以使用 SQL 的服务器方式来管理多个数据库连接和事务。 当应用程序使用 SQL 的服务器模式时,IBM i 操作系统会将作业中的连接用作当前数据库上下文的封装更强的表示,这比 IBM i 以前所允许的要强。 它允许由多个用户连接到数据库,由相同或不同用户连接到数据库的多个连接,以及通过与数据库的连接存在多个独立事务。

    在应用程序中进行数据访问之前,请使用下列其中一种机制来激活 SQL 的服务器方式:

    • 使用开放式数据库连接 (ODBC) API , SQLSetEnvAttr() 并在执行任何数据访问之前将 SQL_ATTR_SERVER_MODE 属性设置为 SQL_TRUE。
    • 在执行任何数据访问之前,请使用 Change Job API, QWTCHGJB() 并设置 "结构化查询语言的服务器方式" 密钥。
    • 使用 Java™ 数据库连接 (JDBC) 来访问数据库。 JDBC 自动使用服务器方式来保留 JDBC的必需语义。
    SQL 行为的服务器方式
    • 对于嵌入式 SQL ,作业中的每个线程都是可以落实或回滚的单独事务,即使该线程中有多个连接也是如此。
    • 对于 ODBC,调用级别接口 (CLI) 和 JDBC,每个连接句柄都表示与数据库的独立连接,并且可以落实并用作单独的实体。

    SQL 的 CLI 是线程安全的。

  • 可执行事务

    引入线程不会更改可落实事务的作用域。 可以将可落实工作单元的作用域限定为作业级别落实定义或激活组级别落实定义。 线程落实或回滚操作将落实或回滚在落实定义下执行的所有操作。 如果需要一个应用程序,其中每个线程 (或线程组) 都具有单独的可落实事务,那么必须将服务器方式用于 SQL ,或者使用单独的激活组来管理这些事务。