我有一个属于主题模型的评论模型。在Comment模型中,我有一个before-create回调

def on_create
  Topic.transaction(:require_new => true) do
    Topic.connection.execute('SET TRANSACTION ISOLATION LEVEL SERIALIZABLE')
    self.topic.increment!(:comment_counter) if conditions
  end
end

问题是我得到一个ActiveRecord::StatementInvalid: PGError: ERROR: SET TRANSACTION ISOLATION LEVEL must be called before any query
是否有其他方法设置事务隔离级别?

最佳答案

PostgreSQL要求在事务启动后和任何DML(SELECT、INSERT、DELETE等)语句之前执行SET TRANSACTION语句。从文档来看,所有这些工作都必须通过连接对象而不是事务对象来完成。类似于(未经测试的)

Topic.connection.begin_db_transaction
  Topic.connection.execute('SET TRANSACTION ISOLATION LEVEL SERIALIZABLE')
  # Other things go here. I'd test with another literal SQL statement to make
  # sure it works like I'd hope it does. Then possibly try rewriting in Rails.
Topic.connection.commit_db_transaction

我真希望我错了。
另一个令人讨厌的选择是更改PostgreSQL服务器上所有事务的默认隔离级别。(搜索http://www.postgresql.org/docs/current/static/runtime-config-client.html查找“默认事务隔离”。)但这感觉就像用大炮杀死苍蝇。

10-07 12:34
查看更多