我比较关心什么时候出 ruby 的 ACE 啊
#19 楼 @spacewander 那就继续 Rails 搞起了,反正目前项目也没大到要太多人的地步,我估计两三个人做后端顶天了。记得蝉游记整个团队也就五六个人,照样做的很漂亮。生产力是关键。
#3 楼 @blacktulip 访问量肯定没大到需要到语言层面的地步。
面试过,我开 5K,给我 4K,而且是三个月的试用期,这么缺钱做啥社交
#13 楼 @summer_charlie PHP 在语言层面的混乱不是一个框架所能解决的
我最反感 PHP,我最反感抄袭,楼主全占了
PHP sucks!
为什么我从 PHP 迁移到了 Ruby? 为什么我从 Ruby 迁移到了 Nodejs? 为什么我从 Nodejs 迁移到了 Go? ......
对于类似这样的标题,我总是想说:你好蛋疼。
使用 gem: geokit-rails
https://github.com/geokit/geokit-rails
具体楼主的例子:
geokit_origin = Geokit::LatLng.new(latitude, longitude)
order_sql = User.distance_sql(geokit_origin)
users = User.within(1, origin: geokit_origin).order("#{order_sql} ASC")
这个跟继承毫无关系
#55 楼 @luikore 楼主你最后所说的话,明显与你之前回复的内容不一致啊。。。
一、你所说的默认加锁还不影响性能 1)你所说的不影响性能,有依据吗? 2)如果真的不影响性能,奥妙在哪里?(因为我们知道不必要的锁显然会降低性能的)
二、mysql 的做法是错的,让人以为它的隔离级别可以解决数据完整性问题但它事实上没有. ” mysql 怎么误导你让你以为可以了?是它的文档,还是你想当然?
三、其次 repeatable read 隔离等级首先要做的是对已经查询的记录加上 lock 机制禁止更改, 而不是字面上的"可以重复读到一样的值" --- 否则我要你这个事务有何用?我干嘛读第二次?
再说 SQL-92 标准是允许 repeatable read 中出现 phantom read 的,但不允许读取过的记录被别的事务更改。
你这几句还是暴漏了你对 SQL92 标准中的“repeatable read”的理解有误呀
你主楼的例子,可以提醒大家正确理解数据库隔离级别,不要以为有了 repeatable read,就可以无脑更新记录了,要跳过自己思维里的坑,给大家提个醒还差不多。而拿这个来说 mysql 有坑,就完全搞错了。
我用的是 PG,对数据库不持立场。
#53 楼 @luikore 首先,你必须承认,你主楼中读取出来 1,然后赋值为 2 的操作,数据库的理解是恰当的,隔离级别的实现也完全符合标准,并不是你所谓的坑。数据库只知道你的最终结果要求是 2,并不知道你的本事是 +1.
其次,对于你的问题,跟隔离级别无关,是你自己不加锁。就拿你的主楼例子好了: select * from accounts where id = n for update # 读取出来是 300,然后你进行各种复杂的运算,结果是 92 update accounts set money = 92 where id = n
你的意思难道数据隔离级别是万能的,如果不是万能的,就是坑?你可以不用锁,反正随便写写,数据库就知道你想干嘛?(还推测你从 1 到 2 的变化是 +1 还是只是想把它的户头变成 2?也拿这个例子来说,从 300 到 92,数据库又该怎么理解?)。其实要解决你所谓的坑,数据库无脑加锁就可以了,它之所以用 MVCC,然后把加锁的选择留给你,就是从性能考虑的,否则为什么自己找麻烦?
然后你举得利息的例子,一样: select * from accounts where id = n for update # 读取是 300,利息 15 update accounts set money = 315 where id = n update banks set money = money - 15 where id = bank_n
#49 楼 @Rei 学习了,谢谢,下次知道了。恢复的内容如下:
1)SQL 标准有缺陷,但不代表对于事务隔离级别的定义有问题,它的定义是明确的,而且 mysql、oracle、pg 都基本支持这个标准;标准是规范,MVCC 是实现,出现的前后代表什么?你想表达什么?
2)你举的这个例子很莫名,你想说 mysql 有 bug 吗?这个语句的上下文是什么?
3)我看的很清楚,我给的例子证明了 PG 对 repeatable read 的实现,已经实现了 SQL 标准中的 serializable,属于过度实现,至于实现细节,我并不 care。
最后,回到本文,你主楼的例子,就是一个明显的逻辑混乱。我可以举个例子:
一个用户本来有 100 块钱,现在有两个事务,一个事务是给这个用户加 10 块钱,另外一个事务是把这个用户的钱改成 500。
如果用户先改成 500,然后加 10 块,这样就是 510;如果这个用户先读取数据是 100,然后一个事务加 10 块提交,另外一个事务改成了 500,就丢失了 10 块,你不就是这个意思吗?
出现这个问题的根本原因在于,改成 500 的这个事务的目的你没搞清楚,他的目的是改成 500,还是加 400?这个是关键。如果你这个事务的目的是加 400,就不是先读取出来 100,然后加 400,而是直接 update uesrs set money = money + 400,这样无论什么事务的顺序都没问题了,你所谓赋值为 500,事务的本身含义就是把他改为 500。懂了吗?
其他问题,我不想扯太远,我只看你主楼的例子,这里面你自己跳到坑里了,跟 mysql 对这个事务隔离级别的实现没关系(我再强调一遍,mysql 对事务隔离级别的实现完全符合 SQL92 标准,你对 SQL92 标准吐槽是你自己的事,但你不该对 mysql 吐槽(再说了,就这个标准你也没有吐槽的理由,主楼的例子是你自己挖的坑))
你主楼的例子无非是: 1)数据本身是 1 2)事务 1:a.读取记录,b.然后加 1 3)事务 2:加 1
如果事务 2 在 a 与 b 之间执行,会导致事务 2 的 +1 丢失。你认为这是 mysql 的实现有问题。
真正的问题是: 事务 1 的意义是什么?你读取出来是 1,然后改成 2,数据库并不知道你的用意是 +1,数据库只知道你的目的是把他改成 2。数字从 1 到 2,我们可以看出来你的意思是 +1,如果换个例子,你把“姚明”改成“刘翔”,那你的意思又是在做什么运算呢?你如果要实现的就是 +1,你就不该这么写,你应该直接写 update accounts set money = money + 1
换句话来说,你的例子还有另外一个版本: 1)数据本身是姚明 2)事务 1:a.读取记录,b.然后变成刘翔 select * from users where id = n update users set name = '刘翔' where id = n 3)事务 2:改为易建联 update users set name = '易建联' where id = n 这两个事务都是改名,他们没有递进关系,谁后执行,谁就起效(当然是后面改的名字覆盖前面的了),如果这个时候,刘翔改慢了一步,得到了保存,你总不能说”易建联"丢失了吧?
而真正反应你本意的例子也有另外一个版本: 1)数据本身是 1 2)事务 1:加 1 update accounts set money = money + 1 where id = n 3)事务 2:加 1 update accounts set money = money + 1 where id = n
这个例子,还会丢失吗?
1)只要能避免不可重复读取和脏读取,就是对 SQL 标准中 repeatable read 的恰当实现,mysql 没有任何问题。 2)楼主对事务隔离级别的认识不够,恐怕也没了解过 MVCC 的实现方法 3)PG 对 repeatable read 的实现是以 SQL 标准中的 Serializable 来实现的,也就是说避免了不可重复读取和脏读取的同时,还阻止了幻读,这是过度实现,因为标准只禁止了不可出现的情况,并没有规定必须允许出现幻读。文档中明确写出:
...and phantom reads are not possible in the PostgreSQL implementation of Repeatable Read, so the actual isolation level might be stricter than what you select. This is permitted by the SQL standard: the four isolation levels only define which phenomena must not happen, they do not define which phenomena must happen.
参见:http://www.postgresql.org/docs/9.3/static/transaction-iso.html
我不理解本文的加精的理由是什么?