获取数千个并发事务中的确切ID

时间:2018-07-08 08:28:28

标签: sql sql-server iis

我的桌子非常拥挤,有成千上万的日志。每次在数据库中插入新日志时,我都需要使用新日志的ID更新某些表。因此,我使用这两行代码获取了最后一个ID:

var CACHED_POSITION = "CACHED_POSITION";

var x = document.getElementById("currentlocation");

var geocoder;

(function () {
    if (navigator.geolocation) {
        try {
            var position = JSON.parse(window.localStorage[CACHED_POSITION]);
            if (position) {
                successFunction(position);
                return;
            }
        } catch (e) {

        }
        navigator.geolocation.getCurrentPosition(successFunction, errorFunction);
    }
})();

//Get the latitude and the longitude;
function successFunction(position) {
    window.localStorage[CACHED_POSITION] = JSON.stringify(position);

    var lat = position.coords.latitude;
    var lng = position.coords.longitude;//Save to cache
    codeLatLng(lat, lng);
}

恐怕第二行是否从最近的订单中获得另一个ID,因为在一秒钟内有成千上万的新日志。

这是一个示例场景,我知道有内置的方法来获取最近插入的行的ID。但是我的确切问题是,如果服务器(IIS和SQL服务器)中的事务存在逻辑顺序,或者新事务在旧事务之前完成,那么第二行是否获得另一个日志的ID? / p>

3 个答案:

答案 0 :(得分:3)

您的第二个查询肯定有可能从另一笔交易中获得ID。我强烈建议您使用SCOPE_IDENTITY()。在DBMS中提供了这种方法,仅用于这种确切的情况,即您插入一行,然后从该表中选择最后一行,但是在这两次操作之间,其他连接可能会插入新行。

答案 1 :(得分:2)

是的。并发事务可能会导致您尝试执行的操作出现问题。

正确的解决方案是output子句。代码如下:

declare @ids table (id int);

insert into logs (member, refer)
    output inserted.id into @ids
    values (12, 12345);

select *
from @ids;

您可以在网上找到有关OUTPUT为什么更好的讨论。原因如下:

  1. 您可以返回多个列,而不仅仅是身份。
  2. 这是会话安全的和表安全的。
  3. 它处理多行。
  4. SELECTUPDATEDELETE的语法相同。

答案 2 :(得分:1)

如果未在WHERE查询中指定SELECT子句,则在提交更改之前,需要在事务中并在SNAPSHOT隔离级别下执行这些查询。这样,只有当前事务所做的更改才可见。

最好使用SCOPE_IDENTITY()返回在当前连接的最外部范围内生成的最后一个标识值。这与@@IDENTITY的不同之处在于,该值不受可能也生成标识值的触发器的影响。

objcon.execute "insert into logs (member,refer) values (12,12345)"
objcon.execute "select SCOPE_IDENTITY() AS id;"