I think I didn't make what I meant clear enough: What do you think about the following:
. Insert record . Calculate balance by summing all records before (including) the one you just inserted (and I think you will agree this is not an extremely complex query) . If balance is positive, it's approved (and you'd probably want to change some status field to reflect that) . If balance is negative, it's refused - and you can change status (or delete, though I wouldn't recommend that) Nothing prevents us from differentiating inserting a record and approving the transaction, right? Depending on whether you use a status field or not, and which transactions you take into account to know whether you will approve, you can get on the safe side. Just assuming that a pending transaction (that is, a transaction that has been inserted but not approved yet) will be approved should prevent approving a withdrawal you should be refusing (but could lead you to refuse one you should be approving if your process is too long) The day performance becomes an issue, you can look into alternate solutions, such as indeed storing the current balance somewhere. Le 21 août 2012 01:26, "Melvyn Sopacua" <m.r.sopa...@gmail.com> a écrit : > On 20-8-2012 19:37, Thomas Orozco wrote: > > > Circumvent the problem with smarter design: don't store the money on the > > object, make the user's money the sum of all their transactions (credit - > > debit). > > You get lesser performance, but you also get history! > > This does not circumvent the problem but aggravates it. The problem is > how to determine if a withdrawal is allowed before doing the withdrawal. > Not having the current balance available but instead having to do > complex queries on a possibly huge set of rows, increases the chances of > transactions being OK'd that should not be when multiple withdrawals are > sent in parallel. > > Alexis has mentioned some options, but the real safeguard is to make > current balance field a positive decimal field and propagate this to the > database layer by ensuring a constraint is created. Even if two > transactions in parallel are working with the same initial balance, the > constraint will deny at least one of them. This is also why you should > enclose the entire process (add withdrawal to statement, decrease the > balance) in a single transaction. Possibly the > @transaction.commit_on_success decorator may prove useful. > > -- > Melvyn Sopacua > > -- > You received this message because you are subscribed to the Google Groups > "Django users" group. > To post to this group, send email to django-users@googlegroups.com. > To unsubscribe from this group, send email to > django-users+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/django-users?hl=en. > > -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.