At the risk of heating things up even more, I wanted to comment on DHH''s assertion that people should just move all their validation/integrity code out of the database. This approach is doomed to fail as things get more complicated because you can''t implement ACID semantics efficiently at the OO layer because you do not have access to all of the data, with current values, at commit time. This is a common OO layer problem (every single one has it, AFAIK), and by being subtle, is even more likely to be uncaught. The problem goes like this: when you commit values to the database, the DB layer should check to see if those objects have been changed since they were fetched. If they have, an exception should be thrown. I don''t get the sense that AR actually does this now, because to implement it, you have to keep an extra copy of the rows fetched around to compare against the current values in the database, and I didn''t see that in my walk through of the code. Correct me if I''m wrong here. However, even with the above check, inconsistencies can still creep in. The problem is that we''re only checking for changes against those rows that we''re committing. If any of the values in those rows are based on values in rows we''re not committing, those uncommitted rows won''t be checked for changes. This is the fundamental problem with OO mapping layers, and I''ve yet to find a framework that handles it correctly. (WebObjects doesn''t, and last I checked, Hibernate doesn''t either.) The solution is to do validation/constraints in the database. Only the database has access to all of the data at commit time. Only the database knows what values are current. Only the database can insure that the values in the database stay consistent. It''s not possible, fundamentally, to do this at the OO level _without_ re-implementing the database at that level--which defeats the purpose of an OO layer entirely. I bring this up because I''m getting the impression on the list that "you can do validation in the OO layer or in the database--your choice." As if the only tradeoff is ease of implementation. The tradeoff is also correctness, integrity, etc. Implementing constraints in the database is only "harder" than OO validation if you''re comparing apples to oranges. Of course, many applications (and probably a great many web applications) won''t bump into these problems. In those cases, DHH''s approach is perfectly fine and probably preferable. Another solution is to use something like Madeleine (although Madeleine doesn''t implement transactions at this point). Best, Eric
I''ll bite. ActiveRecord::Base.transaction do "Look ma! I''m ACID compliant at the OO level!" end But if you want to perform optimistic locking on your db, go for it. I don''t think AR should enforce that "design" decision though. Also, IMHO, validation (just like security) should be everywhere in your app... front-end thru to the back-end. So you''re right saying it should be in the db... but it should also be in the app to some extent. Again, IMHO. Cheers... On Thu, 9 Dec 2004 11:44:21 -0800, Eric Ocean <subscriber-npdh1YFn4ZDQT0dZR+AlfA@public.gmane.org> wrote:> At the risk of heating things up even more, I wanted to comment on > DHH''s assertion that people should just move all their > validation/integrity code out of the database. This approach is doomed > to fail as things get more complicated because you can''t implement ACID > semantics efficiently at the OO layer because you do not have access to > all of the data, with current values, at commit time. This is a common > OO layer problem (every single one has it, AFAIK), and by being subtle, > is even more likely to be uncaught. > > The problem goes like this: when you commit values to the database, the > DB layer should check to see if those objects have been changed since > they were fetched. If they have, an exception should be thrown. I don''t > get the sense that AR actually does this now, because to implement it, > you have to keep an extra copy of the rows fetched around to compare > against the current values in the database, and I didn''t see that in my > walk through of the code. Correct me if I''m wrong here. > > However, even with the above check, inconsistencies can still creep in. > The problem is that we''re only checking for changes against those rows > that we''re committing. If any of the values in those rows are based on > values in rows we''re not committing, those uncommitted rows won''t be > checked for changes. This is the fundamental problem with OO mapping > layers, and I''ve yet to find a framework that handles it correctly. > (WebObjects doesn''t, and last I checked, Hibernate doesn''t either.) > > The solution is to do validation/constraints in the database. Only the > database has access to all of the data at commit time. Only the > database knows what values are current. Only the database can insure > that the values in the database stay consistent. It''s not possible, > fundamentally, to do this at the OO level _without_ re-implementing the > database at that level--which defeats the purpose of an OO layer > entirely. > > I bring this up because I''m getting the impression on the list that > "you can do validation in the OO layer or in the database--your > choice." As if the only tradeoff is ease of implementation. The > tradeoff is also correctness, integrity, etc. Implementing constraints > in the database is only "harder" than OO validation if you''re comparing > apples to oranges. > > Of course, many applications (and probably a great many web > applications) won''t bump into these problems. In those cases, DHH''s > approach is perfectly fine and probably preferable. Another solution is > to use something like Madeleine (although Madeleine doesn''t implement > transactions at this point). > > Best, Eric > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
If I learned one thing from reading mailing lists over the past 10 years than its that you can find a good argument for just about everything. That doesn''t mean its the right thing to do. If you disagree with fundamental things in davids libraries than its time for you to move on. The reason why active record is different from other libraries is the fact that its different from other libraries. Its crafted with the programmer in mind and this has created a buzz far wider than just the ruby scene which clearly indicates that its a good piece of work. Now back to the topic, why you are trying to force locking into the library is beyond me. You obviously know a thing or two about it so why don''t you implement it in whatever application you write? Chances are you can make a module out of it.... On Thu, 9 Dec 2004 11:44:21 -0800, Eric Ocean <subscriber-npdh1YFn4ZDQT0dZR+AlfA@public.gmane.org> wrote:> At the risk of heating things up even more, I wanted to comment on > DHH''s assertion that people should just move all their > validation/integrity code out of the database. This approach is doomed > to fail as things get more complicated because you can''t implement ACID > semantics efficiently at the OO layer because you do not have access to > all of the data, with current values, at commit time. This is a common > OO layer problem (every single one has it, AFAIK), and by being subtle, > is even more likely to be uncaught. > > The problem goes like this: when you commit values to the database, the > DB layer should check to see if those objects have been changed since > they were fetched. If they have, an exception should be thrown. I don''t > get the sense that AR actually does this now, because to implement it, > you have to keep an extra copy of the rows fetched around to compare > against the current values in the database, and I didn''t see that in my > walk through of the code. Correct me if I''m wrong here. > > However, even with the above check, inconsistencies can still creep in. > The problem is that we''re only checking for changes against those rows > that we''re committing. If any of the values in those rows are based on > values in rows we''re not committing, those uncommitted rows won''t be > checked for changes. This is the fundamental problem with OO mapping > layers, and I''ve yet to find a framework that handles it correctly. > (WebObjects doesn''t, and last I checked, Hibernate doesn''t either.) > > The solution is to do validation/constraints in the database. Only the > database has access to all of the data at commit time. Only the > database knows what values are current. Only the database can insure > that the values in the database stay consistent. It''s not possible, > fundamentally, to do this at the OO level _without_ re-implementing the > database at that level--which defeats the purpose of an OO layer > entirely. > > I bring this up because I''m getting the impression on the list that > "you can do validation in the OO layer or in the database--your > choice." As if the only tradeoff is ease of implementation. The > tradeoff is also correctness, integrity, etc. Implementing constraints > in the database is only "harder" than OO validation if you''re comparing > apples to oranges. > > Of course, many applications (and probably a great many web > applications) won''t bump into these problems. In those cases, DHH''s > approach is perfectly fine and probably preferable. Another solution is > to use something like Madeleine (although Madeleine doesn''t implement > transactions at this point). > > Best, Eric > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Tobi http://blog.leetsoft.com
On Thu, 9 Dec 2004, Tobias Luetke wrote:> Now back to the topic, why you are trying to force locking into the > library is beyond me.>From my reading of his post, he''s not trying to force locking at all; infact he doesn''t even want locking: he wants atomic multiple updates. This is actually very important stuff as soon as you get into any sort of sophisticated accounting systems. For example, when you charge someone for a service and do fulfilment of it (e.g., someone gives you a credit card number and you add another year of service to their account), you really want as much of that transaction as possible to be atomic. If you mark the order as fulfilled, you also want the user marked as having another year of service, and if either marking it as fulfilled or the fulfillment itself fails, you want both things not to be updated. When you can''t do this (as, for example, you can''t put the charging of the card itself in the same transaction as the database write), you start to get into complex multi-stage actions that can be left in an incomplete state, and you need to audit these (i.e., go back later, find out what happened, and fix up things appropriately). For example, if you authorize the charge on the card, write your DB, charge the card, but get no response to the charge, you don''t know if the credit card has been charged or not. So you need to go check with whomever holds your merchant account to find out, and then go back and either mark the pending transction as ok or reverse it or try to charge the card again. cjs -- Curt Sampson <cjs-gHs2Wiolu3leoWH0uzbU5w@public.gmane.org> +81 90 7737 2974 http://www.NetBSD.org Make up enjoying your city life...produced by BIC CAMERA
Eric Ocean <subscriber-npdh1YFn4ZDQT0dZR+AlfA@public.gmane.org> wrote:> At the risk of heating things up even more, I wanted to comment > on DHH''s assertion that people should just move all their > validation/integrity code out of the database. This approach is doomed > to fail as things get more complicated because you can''t implement > ACID...On Thu, 9 Dec 2004, Steve Kellock wrote:> ActiveRecord::Base.transaction do > "Look ma! I''m ACID compliant at the OO level!" > endErr, you just moved your integrity code back into the database when you did that. (Or, possibly worse yet, you''re using MySQL instead of a DBMS and it''s pretending it''s doing the stuff in a transaction when it isn''t.) cjs -- Curt Sampson <cjs-gHs2Wiolu3leoWH0uzbU5w@public.gmane.org> +81 90 7737 2974 http://www.NetBSD.org Make up enjoying your city life...produced by BIC CAMERA