Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.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
Sql server 具有并发控制的存储过程_Sql Server_Stored Procedures_Concurrency - Fatal编程技术网

Sql server 具有并发控制的存储过程

Sql server 具有并发控制的存储过程,sql-server,stored-procedures,concurrency,Sql Server,Stored Procedures,Concurrency,我正在尝试编写一个存储过程,如SELECT,它应该可以预订出租房屋 create table rental\u house ( 房屋id int标识主键, 瓦查尔(50岁), 地址:varchar(100), 威克诺国际酒店, 空位 ) 如果房子是空的,则应在周末进行预订和更新 如果房子被预订了,应该写一个错误代码 应该有并发控制 创建过程预订 (@house_id INT, @威克诺国际酒店, @空位) 作为 开始训练 创建过程预订 作为 开始事务 声明@house\u id int 选择@

我正在尝试编写一个存储过程,如
SELECT
,它应该可以预订出租房屋

create table rental\u house
(
房屋id int标识主键,
瓦查尔(50岁),
地址:varchar(100),
威克诺国际酒店,
空位
)
如果房子是空的,则应在
周末进行预订和更新

如果房子被预订了,应该写一个错误代码

应该有并发控制

创建过程预订
(@house_id INT,
@威克诺国际酒店,
@空位)
作为
开始训练
创建过程预订
作为
开始事务
声明@house\u id int
选择@house\u id=house\u id
声明@weekno int
选择@weekno=weekno
声明@空位
选择@空闲=空闲

如果(@house\u id=house\u id)和(@weekno=weekno)和(@emptable一个更新总是在一个事务中运行,那么尝试相同更新的两个会话将被序列化(一个会话将发生在另一个会话之前)。因此,您只需在更新预订时检测预订是否已经更新

一种简单的方法是在
空闲=1
上筛选更新,然后在更新后检查
@@rowcount
,查看它是否影响任何行。例如:

update Booking set vacant = 0
where house_id = @house_id
  and week_no = @weekno
  and vacant = 1

if @@rowcount = 0
begin
  throw 50001, 'House not vacant for that week', 1;
end
如果在单独的查询中选中
empty
,则需要显式事务和
updlock
提示,以便状态检查会话获取并保留一个锁,以防止另一个会话更改状态,例如:

begin transaction

declare @vacant bit = 
  (
     select vacant 
     from Booking with (updlock)
     where house_id = @house_id
        and week_no = @weekno
  )

if @vacant = 1
begin
  update Booking set vacant = 0
  where house_id = @house_id
    and week_no = @weekno
  commit transaction
end
else
begin
    rollback
    throw 50001, 'House not vacant for that week', 1;
end

一个更新总是在一个事务中运行,因此尝试相同更新的两个会话将被序列化(一个在另一个之前发生)。因此,您只需在更新预订时检测预订是否已更新

一种简单的方法是在
空闲=1
上筛选更新,然后在更新后检查
@@rowcount
,查看它是否影响任何行。例如:

update Booking set vacant = 0
where house_id = @house_id
  and week_no = @weekno
  and vacant = 1

if @@rowcount = 0
begin
  throw 50001, 'House not vacant for that week', 1;
end
如果在单独的查询中选中
empty
,则需要显式事务和
updlock
提示,以便状态检查会话获取并保留一个锁,以防止另一个会话更改状态,例如:

begin transaction

declare @vacant bit = 
  (
     select vacant 
     from Booking with (updlock)
     where house_id = @house_id
        and week_no = @weekno
  )

if @vacant = 1
begin
  update Booking set vacant = 0
  where house_id = @house_id
    and week_no = @weekno
  commit transaction
end
else
begin
    rollback
    throw 50001, 'House not vacant for that week', 1;
end

一个简单的
更新…where house\u id=@house\u id and ungable=1
已经可以确保并发控制。我尝试了这个,但它不起作用;一个简单的
更新…where house\u id=@house\u id and ungable=1
已经可以确保并发控制。我尝试了这个,但它不起作用;