Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#-范围为_identity()的并发插入_C#_Sql Server_Concurrency_Scope - Fatal编程技术网

c#-范围为_identity()的并发插入

c#-范围为_identity()的并发插入,c#,sql-server,concurrency,scope,C#,Sql Server,Concurrency,Scope,我们有十几个客户端,它们使用一个程序集以简单SQL语句的形式将数据插入我的SQL Server 2012 有两个带有标识列和外键的表(例如[User]和[Location]) 语句的执行总是相同的:createuser,将新id另存为创建位置的外键 在伪代码中: //open DB Connection Connection.Open(); //Insert user "INSERT INTO User (Name, Birthdate) VALUES ("Smith", "1.1.1919"

我们有十几个客户端,它们使用一个程序集以简单SQL语句的形式将数据插入我的SQL Server 2012

有两个带有标识列和外键的表(例如
[User]
[Location]

语句的执行总是相同的:createuser,将新id另存为创建位置的外键

在伪代码中:

//open DB Connection
Connection.Open();

//Insert user
"INSERT INTO User (Name, Birthdate) VALUES ("Smith", "1.1.1919");
 SELECT SCOPE_IDENTITY();" //save the new ID in var "newID"

//Execute Statement
ExecuteQuery();

//Insert Location
"INSERT INTO Location(Country, City, User_ID) VALUES ("Germany", "Cologne", newID)"

//Execute Statement
ExecuteQuery();

//close Connection
Connection.Close();
到目前为止没有什么神奇之处……但是如果我在多个客户端或并行线程上同时运行此代码,
SCOPE\u IDENTITY()
是否有可能检索另一个客户端/线程创建的
用户的新创建ID

特别是在插入用户和
Scope\u Identity()

OUTPUT
子句可能是澄清问题的另一种选择吗

会话
对应于您与数据库的当前连接(Ado.Net/EF/SSMS等)。一个应用程序可能有多个到数据库的会话

范围是执行SQL命令的上下文。假设您调用某个T-SQL,它调用一个存储过程,执行某个触发器。T-SQL将有一个作用域,然后是存储过程中代码的另一个嵌套作用域,然后是触发器中代码的另一个作用域。因此,当您使用时,您正在检索您所在范围内最后插入的PK Id

本质上,不同的会话意味着不同的范围

相反,返回会话中最后插入的ID。它没有“范围感知”。如果您在表中插入,并且触发器在幕后执行某些操作,则有机会获得触发器插入的ID


请注意,如果回滚已生成PK Id的事务,则PK计数器不会返回到上一个值,因为回滚,该行不会提交,但会存在一个小漏洞—表PK连续性…

SCOPE\u IDENTITY
是作用域内的标识。因此,具有不同作用域的并发连接不会重叠。因此,如果每个连接在db上都有自己的作用域,那么作用域和会话之间有什么区别呢?感谢您的解释!第三种可能性是
IDENT_CURRENT
,它将返回任何会话和任何作用域上的特定表的值-对于我的应用程序来说,这并不是真正正确的事情。有一点“非常明显”的事情我忘了说:作用域(ex的存储过程)不会在不同会话之间共享,也不会在不同调用之间共享。如果在同一会话中并行调用同一SP 16次,它将创建不同的16个作用域