ActiveRecord Changed :include Behavior?
August 12th, 2009
Just figured out that ActiveRecord 2.2 generates SQL for
Company.find(:all, :include => :people)as something like
SELECT * FROM company SELECT person.* FROM person WHERE person.id in (...)In 2.1.x, it used to generate SQL as something like
SELECT * FROM company LEFT OUTER JOIN person ON person.company_id = company.id
It seems for the sake of performance…the current statements return smaller data set. However, it could generate a very long SQL statement if you have lots of ‘people’ in this case, and thus spend longer to parse and execute.
And…WHEN did this change happen? I’m wondering…
Hack Rails的事务机制
October 19th, 2008
- ActiveRecord不支持嵌套事务。
- 为了简单我们在ApplicationController里做了个filter,于是所有POST/PUT/DELETE的action都被包裹在一个事务里,事务边界是整个请求。
- 偏偏有时候你希望让某个操作中的某个部分不被包含在事务里。原因是当某些操作同时进行,你想看到的不是原子的结果,而是所有同时进行的操作汇总的最终结果
- 比如说,“审核改进措施”这个操作中包含了“重新算分”。
- 某企业有两项改进措施R1和R2,分别对应考核类别C1和C2。C1的原始分数是98,C2的原始分数是89。
- R1能给C1加回1分,R2能给C2加回11分。也就是说审核R1之后C1变成99分,审核R2后C2变成100分。
- 但,“重新算分”是在整个“审核”的事务之中的,于是如果R1和R2同时审核,你一定会看到下列两种原子结果之一:
- C1 99分,C2 89分;或者
- C1 98分,C2 100分。
- 其实这个时候我们不想让“重新算分”跟“审核”成为原子操作,我们希望把“算分”从“审核”的事务里拿出来,这样最后一次算分一定能体现最终的分数状态。
- 可以开一个 线程 或者进程(比如 Kernel.system )把算分的逻辑分出来。
- 因为可以确定“算分”不会跟“审核”发生死锁,所以把这个线程join起来。
- 一定要小心,要是算分跟审核修改到同一条数据那么就会死锁…因为审核等待算分线程结束,而算分线程等待审核交出数据锁。
- 多个算分线程之间是不会死锁滴…为了确保时序可以一上来就锁自己最后要更新的分数记录。
给Rails应用搞上数据库视图
May 30th, 2008
第一次在Rails应用里用到了 MySQL 5的视图 ,留个纪念。
Rails创建大概50,000个ActiveRecord对象就会很慢(大概50~60秒,在我的双核Mac Mini上),为了对付一个报表,就搞了一个视图。整体时间从70秒降到7秒。
Rails预先定义的rake任务中有db:test:prepare(里面调用db:test:clone_structure),但这个任务只把development库的所有表复制到test,不会复制视图,所以要自己在Rakefile里准备test库。
以上。



