使用绑定会话

绑定会话有利于在同一台服务器上的多个会话之间协调操作。绑定会话允许一个或多个会话共享相同的事务和锁,并可以使用同一数据,而不会有锁冲突。可以从同一个应用程序内的多个会话中创建绑定会话,也可以从包含不同会话的多个应用程序中创建绑定会话。

若要参与绑定会话,会话必须调用 sp_getbindtokensrv_getbindtoken(通过开放式数据服务)来获取一个绑定令牌。绑定令牌是一个字符串,它唯一地标识每个绑定事务。然后,将绑定令牌发送给要与当前会话绑定的其他会话。其他会话通过调用 sp_bindsession,并使用从第一个会话中接收到的绑定令牌绑定到事务。

注意注意

会话必须包含一个活动的用户事务,sp_getbindtokensrv_getbindtoken 才能成功。

必须将绑定令牌从执行第一个会话的应用程序代码传输到随后将其会话绑定到第一个会话的应用程序代码。没有应用程序可以用来获取由另一个进程启动的事务绑定令牌的 Transact-SQL 语句或 API 函数。可以用来传输绑定令牌的方法包括:

  • 如果所有会话都是从同一个应用程序进程启动的,绑定令牌就可以存储在共用内存中,也可以作为参数传递到函数中。

  • 如果会话是从不同的应用程序进程启动的,那么可以使用进程间通信 (IPC)(例如,远程过程调用 [RPC] 或动态数据交换 [DDE])来传输绑定令牌。

  • 可以将绑定令牌存储在 SQL Server 数据库引擎实例中的某个表中,该表可由要绑定到第一个会话的进程读取。

在一组绑定会话中,任何时候只能有一个会话是活动的。如果有一个会话正在实例上执行一个语句,或包含从实例挂起的结果,则在当前会话完成处理或取消当前语句之前,其他绑定到该会话的会话都不能访问该实例。如果该实例正在忙于处理来自另一个绑定会话的语句,则将出现错误,指明事务空间正在使用中,会话应稍后重试。

绑定会话后,每个会话仍保留其隔离级别设置。使用 SET TRANSACTION ISOLATION LEVEL 更改某个会话的隔离级别设置不会影响绑定到该会话的任何其他会话的设置。

绑定会话的类型

有两种类型的绑定会话:本地绑定会话和分布式绑定会话。

  • 本地绑定会话

    允许绑定会话共享单个数据库引擎实例中的单个事务的事务空间。

  • 分布式绑定会话

    允许在使用 Microsoft 分布式事务处理协调器 (MS DTC) 提交或回滚整个事务之前,绑定会话可以共享跨越两个或多个实例的同一事务。

分布式绑定会话不是用字符串绑定令牌标识,而是用分布式事务标识号标识。如果某个本地事务中涉及到某个绑定会话,且该会话使用 SET REMOTE_PROC_TRANSACTIONS ON 在远程服务器上执行 RPC,则 MS DTC 将该本地绑定事务自动提升为分布式绑定事务,并且 MS DTC 会话也会启动。

何时使用绑定会话

在早期版本的 SQL Server 中,绑定会话主要用于开发必须执行 Transact-SQL 语句(代表调用它们的进程)的扩展存储过程。让调用进程在绑定令牌中作为扩展存储过程的一个参数进行传递,可使该过程加入到调用进程的事务空间中,从而将扩展存储过程与该调用进程结合在一起。

在 SQL Server 数据库引擎中,使用 CLR 编写的存储过程比扩展存储过程更安全、具有更高的伸缩性并且更稳定。CLR 存储过程使用 SqlContext 对象(而非 sp_bindsession)联接调用会话的上下文。

绑定会话可以用来开发三层应用程序,在这些应用程序中,业务逻辑合并到在单个业务事务上协同工作的单独程序中。必须对这些程序进行编码,以仔细协调它们对数据库的访问。由于两个会话共享同一个锁,因此两个程序不得同时修改同一数据。在任何时间点,事务中只能有一个会话在执行,不存在并行执行操作。只能在定义完善的时间点于会话之间切换事务,例如,已完成所有 DML 语句且已检索其结果时。