存储过程与标准选择更新,避免锁定

时间:2017-09-26 16:12:59

标签: sql locking sybase database-locking

为了检索ID,我首先在两个后续查询中进行选择,然后进行更新。

问题是我遇到了锁定行的问题。我已经读过,将这两个语句,Select和Update放在一个存储过程中,它有助于锁定。这是真的吗?

我运行的查询是:

select counter 
from dba.counter_list 
where table_name = :TableName

update dba.counter_list 
set counter = :NewCounter 
where table_name = :TableName

问题是多个用户可能会选择同一行,也可能会更新同一行。

2 个答案:

答案 0 :(得分:0)

表counter_list是否同时由多个客户端访问?

OLTP的最佳实践是调用将在一个事务中执行更新逻辑的存储过程。

检查表dba.counter_list是否有列table_name的索引。 还要检查它是否已锁定行级别。

答案 1 :(得分:0)

假设:

  • 您正在使用Sybase ASE
  • 您的select会返回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获取所需行(或页面/表格的独占锁定,具体取决于表格设计和锁定方案)
  • 使用独占锁定,您可以检索当前值并使用单个语句设置新值

您是通过SQL批处理还是存储过程调用提交上述内容取决于您和您的DBA来决定......

  • 如果禁用语句缓存,则每次提交到数据服务器时都需要编译SQL批处理
  • 如果启用了语句缓存,并且您定期提交此SQL批处理,那么之前的查询计划仍有可能仍在语句/过程缓存中,从而消除了(代价高昂的)编译步骤
  • 如果先前存储的proc(查询)计划的副本不在过程高速缓存中,那么在将(proc)查询计划加载到过程中时,您将产生(昂贵的)编译步骤
  • 如果出现语法/逻辑/性能问题(与编辑和编译前端应用程序相反),存储过程通常更容易替换。
  • ...为SQL批处理与存储过程(vs准备好的语句?)vs ???添加你最喜欢的参数...