存储过程与标准 select 更新,避免锁定
Stored procedures vs standard select update, avoid locks
为了检索 ID,我首先执行 select,然后在两个后续查询中进行更新。
问题是我遇到了锁定行的问题。我读过将这两个语句 Select 和 Update 放在一个存储过程中有助于锁定。这是真的吗?
我运行的查询是:
select counter
from dba.counter_list
where table_name = :TableName
update dba.counter_list
set counter = :NewCounter
where table_name = :TableName
问题是,多个用户可能会 select 访问同一行,也可能会更新同一行。
tablecounter_list是否被多个客户端同时访问?
OLTP 的最佳实践是调用将在一个事务中执行更新逻辑的存储过程。
检查 table dba.counter_list 在列 table_name 上是否有索引。
还要检查它是否已锁定行级别。
假设:
- 您正在使用 Sybase ASE
- 您的
select
returns counter
的单个值
- 您可能希望旧的
counter
值用于执行更新以外的其他目的
考虑以下 update
语句,该语句应消除多个用户可能同时出现的任何竞争条件 运行 您的 select/update
逻辑:
declare @counter int -- change to the appropriate datatype
update dba.counter_list
set @counter = counter, -- grab current value
counter = :NewCounter -- set to new value
where table_name = :TableName
select @counter -- send previous counter value to client
update
获得所需行的独占锁(或 page/table 取决于 table 设计和锁定方案)
- 有了独占锁,您可以通过一条语句检索当前值并设置新值
是否通过 SQL 批处理或存储过程调用提交上述内容由您和您的 DBA 决定...
- 如果语句缓存被禁用,SQL 批处理将需要在每次提交到数据服务器时编译
- 如果启用了语句缓存,并且您定期提交此 SQL 批处理,那么之前的查询计划有可能仍在 statement/procedure 缓存中,从而消除了(昂贵的)编译步骤
- 如果先前存储的过程(查询)计划的副本不在过程缓存中,那么在将(过程)查询计划加载到过程缓存中时,您将招致(昂贵的)编译步骤
- 在出现 syntax/logic/performance 问题时,存储过程通常更容易替换(与编辑和可能编译前端应用程序相反)
- ...为 SQL 添加您(最不喜欢的)参数 batch vs stored proc(vs prepared statement?)vs ??? ...
为了检索 ID,我首先执行 select,然后在两个后续查询中进行更新。
问题是我遇到了锁定行的问题。我读过将这两个语句 Select 和 Update 放在一个存储过程中有助于锁定。这是真的吗?
我运行的查询是:
select counter
from dba.counter_list
where table_name = :TableName
update dba.counter_list
set counter = :NewCounter
where table_name = :TableName
问题是,多个用户可能会 select 访问同一行,也可能会更新同一行。
tablecounter_list是否被多个客户端同时访问?
OLTP 的最佳实践是调用将在一个事务中执行更新逻辑的存储过程。
检查 table dba.counter_list 在列 table_name 上是否有索引。 还要检查它是否已锁定行级别。
假设:
- 您正在使用 Sybase ASE
- 您的
select
returnscounter
的单个值
- 您可能希望旧的
counter
值用于执行更新以外的其他目的
考虑以下 update
语句,该语句应消除多个用户可能同时出现的任何竞争条件 运行 您的 select/update
逻辑:
declare @counter int -- change to the appropriate datatype
update dba.counter_list
set @counter = counter, -- grab current value
counter = :NewCounter -- set to new value
where table_name = :TableName
select @counter -- send previous counter value to client
update
获得所需行的独占锁(或 page/table 取决于 table 设计和锁定方案)- 有了独占锁,您可以通过一条语句检索当前值并设置新值
是否通过 SQL 批处理或存储过程调用提交上述内容由您和您的 DBA 决定...
- 如果语句缓存被禁用,SQL 批处理将需要在每次提交到数据服务器时编译
- 如果启用了语句缓存,并且您定期提交此 SQL 批处理,那么之前的查询计划有可能仍在 statement/procedure 缓存中,从而消除了(昂贵的)编译步骤
- 如果先前存储的过程(查询)计划的副本不在过程缓存中,那么在将(过程)查询计划加载到过程缓存中时,您将招致(昂贵的)编译步骤
- 在出现 syntax/logic/performance 问题时,存储过程通常更容易替换(与编辑和可能编译前端应用程序相反)
- ...为 SQL 添加您(最不喜欢的)参数 batch vs stored proc(vs prepared statement?)vs ??? ...