【问题标题】:Rails: Mysql2::Error: Commands out of syncRails:Mysql2::Error:命令不同步
【发布时间】:2015-11-15 06:20:27
【问题描述】:

我在 Rails 中直接使用 Model.connection 运行 MySQL 存储过程。所有数据都正确插入数据库并按预期返回,但我在测试中收到以下错误:

  1. ActiveRecord::StatementInvalid: Mysql2::Error: 命令不同步;您现在无法运行此命令:ROLLBACK

  2. ActiveRecord::StatementInvalid: Mysql2::Error: 命令不同步;您现在无法运行此命令:BEGIN

暂定1:

Model.connection.transaction do
  result = Model.connection.select_value("CALL myStoredProcedure(...);")
end

暂定2:

Model.connection.begin_db_transaction
result = Model.connection.select_value("CALL myStoredProcedure(...);")
Model.connection.commit_db_transaction

暂定3:

result = Model.connection.select_value("CALL myStoredProcedure(...);")
Model.clear_active_connections!

Tentative #3 导致“ActiveRecord::StatementInvalid: Mysql2::Error: Commands out of sync; you can't run this command now: BEGIN”消失。 ROLLBACK 命令的错误仍然存​​在。

我做错了什么?

谢谢

【问题讨论】:

    标签: mysql ruby-on-rails ruby activerecord


    【解决方案1】:

    解决办法是:

    #checkout a connection for Model
    conn = ModelName.connection_pool.checkout
    
    #use the new connection to execute the query
    @records = conn.execute("call procedure('params')")
    
    #checkout the connection
    ModelName.connection_pool.checkin(conn)
    

    Here is the explanation.

    【讨论】:

      【解决方案2】:

      使用 Rails v4.2 和 MySQL2 v0.4.5 我发现几乎所有记录在案的解决方案都行不通。我也不喜欢在活动连接上调用 clear 的想法。所以我经历了一些事情。首先,我尝试以从阅读源代码中找到的最受支持的方式(一个简单的初始化程序)为多个语句设置连接/查询标志。

      Mysql2::Client.default_query_options[:connect_flags] |= Mysql2::Client::MULTI_STATEMENTS
      

      效果很好,我可以验证设置了标志,但是,这并没有解决我的问题。我在一些非常基本的过程中遇到了不同步错误。所以我开始使用放弃结果!方法并将其包装成一个看起来类似于我在 SQL Server 适配器中所做的工作的方法。

      ActiveRecord::ConnectionAdapters::Mysql2Adapter.class_eval do
        def execute_procedure(proc_name, *variables)
          vars = variables.map{ |v| quote(v) }.join(', ')
          response = execute "CALL #{proc_name}(#{vars})", 'Execute Procedure'
          response.each
        ensure
          raw_connection.abandon_results!
        end
      end
      

      现在有了这个,很容易执行 proc/function 并获得基本结果。

      ActiveRecord::Base.connection.execute_procedure :appsptest, 'arg1'
      

      【讨论】:

      • 在 Rails 5.2.3 中使用 mysql2 gem 0.4.10 进行测试,效果很好!非常感谢,应该是经过验证的答案
      【解决方案3】:

      我怀疑您的模型的连接正在尝试同时运行冲突的查询。与其使用Model.connection.select_value,不如尝试使用ActiveRecord::Base.connection.execute

      result = ActiveRecord::Base.connection.execute "CALL myStoredProcedure(...);"
      ActiveRecord::Base.clear_active_connections!
      

      【讨论】:

        猜你喜欢
        • 2020-05-07
        • 2015-10-31
        • 2015-03-05
        • 2021-06-01
        • 1970-01-01
        • 2013-01-11
        • 2020-09-25
        • 1970-01-01
        相关资源
        最近更新 更多