incubator-couchdb-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Metin Akat <>
Subject Re: FIFO/LIFO accountancy
Date Wed, 03 Feb 2010 17:35:10 GMT
Thanks, Brian.
You have summarized the problems we are facing very well. Are you
working on something similar?
One thing for sure, RDBMSs are not a better fit for this kind of
application (at least for the rest of the functionality). Map/Reduce
is one absolutely great way to calculate balances and reports in real
time.  They allow things that are not possible (or at least not
feasible) with RDBMSs. Not to mention how great is replication
(different departments do their accountancy asynchronously and
consolidate at the end of the year).

So far FIFO/LIFO is the only problem we haven't solved in a "perfect"
way. And I guess we can live with it even if it's not absolutely fault

We are quite close to what you have purposed. I guess we'll have to
find "where to cut" between storing the information "batch"-centric
(stock centric) and "document"-centric (in the sense of an invoice)

On Wed, Feb 3, 2010 at 6:37 PM, Brian Candler <> wrote:
> On Wed, Feb 03, 2010 at 05:29:26PM +0200, Metin Akat wrote:
>> So, we need some way to figure out which apples we sell first. (how
>> much value to remove from the warehouse account). In order to do this
>> we need to know how much have we sold till the moment. And this needs
>> to be fault tolerant.
>> For example, if somebody (at some other cash register in the store)
>> sold 3 apples before our deal, our transactions would be quite a bit
>> different. What if this happened one milisecond before we sell our
>> apples?
> It sounds to me like this is a locking problem. You have an inventory of
> (5 apples @ $2), (5 apples @ $3) and you want to remove from these pools
> atomically, *without any chance of going negative*
> So your first thought might be to keep your stock of apples as a single
> document, and use couchdb's 'optimistic locking' to prevent two concurrent
> changes:
> {
>  "id":"apples",
>  "stock":{2.0=>5, 3.0=>5},  // cost price => quantity
> }
> That's fine (on a single couchdb node anyway). But then you want to record
> the sale as another part of the same 'transaction', and post it to your
> sales ledger and the customer's account receivable at the same time.  That
> might work if the details of the sale were stored in the same document as
> the apples (a view can pull them out). e.g.
> {
>  "id":"apples",
>  "stock":{3.0=>4},
>  "purchases":[
>   {"supplier":888, "orderno":123, "line":1, "qty":5, "cost":10.0},
>   {"supplier":888, "orderno":124, "line":1, "qty":5, "cost":15.0}
>  ],
>  "sales":[
>  {"cust":1234, "orderno":9999, "line":1, "qty":6, "price":30.0, "cost":13.0}
>  ]
> }
> But what if one customer decides to purchase apples and pears in the same
> order?  In the event of a power loss, would it be acceptable for half of the
> order to be recorded?
> I think it might. If the order is a separate doc, and the order ID is posted
> against each line item as shown above, you can identify orders which haven't
> been fully processed and hence complete the processing of them when the app
> restarts.
> This gives a very stock-centric view of your business processes. What if
> your business takes apples out of the apples stock and manufactures it into
> cartons of apple juice, which it then sells?
> Maybe an RDBMS would be a better fit :-(
> B.

View raw message