我有一个属于主题模型的评论模型。在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查找“默认事务隔离”。)但这感觉就像用大炮杀死苍蝇。