2017-02-27 29 views
1

我有一个python脚本在Redshift中执行多个sql脚本(一个接一个地)。这些sql脚本中的一些表可以多次查询。例如。表t1可以在一个脚本中选择,并可以在另一个脚本中删除/重新创建。整个过程在一个事务中运行。现在,有时候,我得到了死锁检测错误,并且整个事务被回滚。如果表中存在死锁,我想等待表被释放,然后重试sql执行。对于其他类型的错误,我想回滚事务。从文档看来,直到事务结束时才会释放表锁。我想实现全部或者没有数据变化(这是通过使用事务完成的),但也想处理死锁。有关如何完成这一任务的任何建议?在红移处理锁

回答

0

我将执行所有你是指在一个事务中与重试循环的SQL。下面是我用来处理并发问题和重试(为了简洁起见,伪码)的逻辑。我没有系统无限期地等待锁释放。相反,我会在应用程序中通过重试来处理它。

begin transaction 
while not successful and count < 5 
    try 
     execute sql 
     commit 
    except 
     if error code is '40P01' or '55P03' 
      # Deadlock or lock not available 
      sleep a random time (200 ms to 1 sec) * number of retries 
     else if error code is '40001' or '25P02' 
      # "In failed sql transaction" or serialized transaction failure 
      rollback 
      sleep a random time (200 ms to 1 sec) * number of retries 
      begin transaction 
     else if error message is 'There is no active transaction' 
      sleep a random time (200 ms to 1 sec) * number of retries 
      begin transaction 
    increment count 

关键零部件捕捉每一个type of error,知道哪些情况下需要回滚,并且具有exponential backoff for retries

+0

如果我理解正确,你建议在每个sql脚本之后提交,并只回滚出错的脚本。当出现死锁错误时,是否无法确保所有sql脚本在一个事务下运行? – stech

+1

我建议你在一个事务中运行所有的SQL(我的'execute sql'行)。如果它死锁或失败,则重试整个事情。您也可能对保存点感兴趣,但我从未使用过它们,也不知道它是否可用于redshift:https://www.postgresql.org/docs/current/static/sql-savepoint.html –

+0

忽略我对使用保存点的评论。回滚到保存点不红移可供选择:http://docs.aws.amazon.com/redshift/latest/dg/c_unsupported-postgresql-functions.html –