在PHP中使用SQLSRV Native Client确实连接池会影响@@ IDENTITY吗?

时间:2013-03-19 16:38:23

标签: sql-server insert connection-pooling identity

我在测试中没有问题,但我想知道有数千个并发用户的实时环境。

如果我分别执行两个查询:

insert into table (somecolumnname) values (somedata)

接着是

select @@IDENTITY as lastInsertId

这将为我提供稍后在其他查询中使用的最后一个插入ID。关于@@ IDENTITY(http://msdn.microsoft.com/en-gb/library/aa933167(v=sql.80).aspx)的文件说:

  

@@ IDENTITY函数的范围是执行它的本地服务器。

如果这是本地服务器,如果有人进来并在我执行第二个查询所花费的时间内插入另一个语句,那么我将得到错误的insertID;即使它在交易中?

其次,我在这里阅读了一个有冲突的帐户(http://msdn.microsoft.com/en-gb/library/ms187342.aspx):

The scope of the @@IDENTITY function is current session on the local server on which it is executed. 

因此,如果@@ IDENTITY是基于会话的,那么使用本机客户端和连接池连接时会话的确切内容是什么?根据我对连接池的理解,如果第二个用户在第一个用户访问我的站点时访问该站点; nativec客户端将使用相同的连接,而不是打开第二个单独的连接。如果是这种情况,这与在@@ IDENTITY上分享会话相同,这意味着来自其他用户的插入仍会影响结果吗?

听起来像交易应该确保我从@@ IDENTITY获得正确的价值,但我发现很难找到明确的文件告诉我这是事实,当然这很难在测试环境中测试。

我尝试使用绝对游标同时执行两个查询:

inset into table (somecolumnname) values (somedata);select @@IDENTITY as lastindertid

但问题是这是通过抽象函数运行的,该函数将select @@ identity查询附加到末尾以将脏全局设置为最后一个插入ID(我不能轻易地改变它或者我会这样做)。因为没有sqlsrv_last_result函数,所以如果没有将光标移动太远并检查它是否为空,我无法知道我是否在最后一个结果上;但是这又要求我从try:catch中的每个查询中提取数据(以防止错误从删除中删除数据),然后在光标返回null之前使用最后一次拉动...这当然非常慢。

如果有人设法对此进行测试,或者可以指向定义不冲突的地方,那将非常感激。

谢谢,

1 个答案:

答案 0 :(得分:1)

我已经发现本机客户端(与DBLIB不同)默认设置NOCOUNT意味着INSERT会将受影响行的数量作为结果集返回,这导致了原始问题。

立即运行“SET NOCOUNT ON”,然后在同一个查询批处理中使用SCOPE_IDENTITY()似乎解决了这个问题,因为不要求我运行两个单独的查询来定位选择部分。

将来更多的插入将使用存储过程。