2017-09-26 79 views
0

为了检索ID,我首先在两个相应的查询中进行选择然后进行更新。存储过程与标准选择更新,避免锁

的问题是,我有锁定的行问题。我读过将这两个语句,选择和更新放在一个存储过程中,它有助于锁定。这是真的?

我运行的查询是:

select counter 
from dba.counter_list 
where table_name = :TableName 

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

的问题是,它可能发生多个用户选择同一行,也可能是他们更新同一行。

+0

请张贴您现有的代码并用锁解释您的具体问题。 –

+0

@ PM77-1我做了,谢谢 –

+0

锁是**高度供应商特定的** - 所以请添加一个标签来指定您是否使用'mysql','postgresql','sql-server','oracle ''或'db2' - 或者其他的东西。 –

回答

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批处理或存储的proc调用取决于您和您的DBA来决定...

  • if语句缓存被禁用,一个SQL批处理需要每个
  • 如果启用语句缓存它提交到数据服务器的时间来进行编译,并提交定期这个SQL批处理,然后有一个机会先前的查询计划仍在语句/过程高速缓存中,因此如果先前存储的proc(查询)计划的副本不在过程高速缓存中,则会消除(昂贵的)编译步骤
  • 将(proc)查询计划载入过程cahe
  • 存储过程通常更容易在yntax /逻辑/性能问题(而不是编辑,并可能编译,前端应用程序)
  • ...添加您的(最少)喜欢的SQL批处理参数vs存储过程(vs准备语句? ? ...
+0

非常感谢您的帮助,非常好地提出并解释! –

0

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

用于OLTP的最佳做法是调用,将在一个事务中进行更新逻辑的存储过程。

检查表dba.counter_list对table_name的列的索引。 检查还在于它是行级锁定。