雪花存储过程事务行为不可预测

时间:2021-05-10 04:49:47

标签: stored-procedures snowflake-cloud-data-platform

我已经使用雪花一段时间了,但实际上还没有使用涉及事务的存储过程,我有使用流的要求,一个这样的情况是涉及一些业务逻辑要放入带有条件事务的 sp 中回滚。我已经写了一个这样的程序,但到目前为止还没有成功回滚。

这是我想要实现的伪代码:

CREATE OR REPLACE PROCEDURE TEST_SP(STREAM_NAME varchar,RECORD_ID_KEY varchar)
  RETURNS VARCHAR
  LANGUAGE javascript
  AS
$$

var source_table_row1 = `SELECT RECORD_CONTENT::string from ${STREAM_NAME} limit 1;`;
var statement1 = snowflake.createStatement({sqlText:source_table_row1});
var raw_json='';

try
{
  var result_set1=statement1.execute();
  while (result_set1.next()) 
  {
    raw_json = result_set1.getColumnValue(1);
  }
} catch(err)
{
  var result =  "Failed: Code: " + err.code + "\n  State: " + err.state;
  result += "\n  Message: " + err.message;
  return "detailed error  is:"+result; 
}

snowflake.execute({sqlText:"begin transaction"});
if(raw_json)
{
  try
  {
   
   //run DDL & DML statmetents  

    var result_set2=snowflake.createStatement({sqlText:"DDL STMT"}).execute();
    var rs=snowflake.createStatement({sqlText: "DML STMT"}).execute();
    var rs2=snowflake.createStatement({sqlText: "FINAL DML STMT"}).execute();
 
  }catch(err){

    snowflake.execute ({sqlText: "rollback"});
    var errorMessage= "Failed: Code: " + err.code + "\n  State: " + err.state;
    errorMessage += "\n  Message: " + err.message+"    with net_status="+net_status;
    return errorMessage;
  }
}
else
{

  snowflake.execute({sqlText: "rollback"});
  return "no data present in source table";


}
snowflake.execute({sqlText:"rollback"});

return "successfully completed "
 
$$;


这里的问题是,如果一切顺利,我可以看到 sp 执行所需的操作,但对于查询失败的情况(例如,尝试复制不存在的表单表)。 ,代码进入 catch 块,存储过程完成,但我看不到任何回滚活动的结果。 有人能告诉我我在这里错过了什么。 谢谢。

1 个答案:

答案 0 :(得分:2)

问题是事务中的 DDL 代码:

snowflake.execute({sqlText:"begin transaction"});
...
//run DDL & DML statmetents  

var result_set2=snowflake.createStatement({sqlText:"DDL STMT"}).execute();  -- here
var rs=snowflake.createStatement({sqlText: "DML STMT"}).execute();       
var rs2=snowflake.createStatement({sqlText: "FINAL DML STMT"}).execute();
...
snowflake.execute ({sqlText: "rollback"});
<块引用>

Transactions

显式事务应仅包含 DML 语句和查询语句。 DDL 语句隐式提交活动事务(有关详细信息,请参阅 DDL 部分)。

DDL

每个 DDL 语句都作为单独的事务执行。

如果在事务处于活动状态时执行 DDL 语句,则 DDL 语句:

  • 隐式提交活动事务。

  • 将 DDL 语句作为单独的事务执行。

因为 DDL 语句是它自己的事务,所以不能回滚 DDL 语句;包含 DDL 的事务在您可以执行显式 ROLLBACK 之前完成。