eug*_*gen 3 postgresql transactions ruby-on-rails callback
我有一个评论模型,属于一个主题模型.在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
Run Code Online (Sandbox Code Playgroud)
问题是我得到了ActiveRecord::StatementInvalid: PGError: ERROR: SET TRANSACTION ISOLATION LEVEL must be called before any query.
有没有其他方法来设置事务隔离级别?
从Rails 4开始,#transaction提供了一个:isolation选项:
如果数据库支持为事务设置隔离级别,则可以这样设置:
Run Code Online (Sandbox Code Playgroud)Post.transaction(isolation: :serializable) do # ... end
PostgreSQL要求SET TRANSACTION在事务开始之后和任何DML(SELECT,INSERT,DELETE等)语句之前执行语句.从文档中看,所有这些东西都必须通过连接对象而不是事务对象来完成.像(未经测试的)
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
Run Code Online (Sandbox Code Playgroud)
我真的希望我错了.
一个令人反感的替代方法是更改PostgreSQL服务器上所有事务的默认隔离级别.(在http://www.postgresql.org/docs/current/static/runtime-config-client.html上搜索"default_transaction_isolation".)但感觉就像用大炮杀死苍蝇一样.
| 归档时间: |
|
| 查看次数: |
4199 次 |
| 最近记录: |