modifiedField() and database consistency

In the Expense Management module, I came across – I would say – a classic error in a modifiedField() method. So it looks like it is necessary to point out this type of errors.

As you probably know, the modifiedField() method is located on tables and it is called by a form (or a dataset) when any field is changed. It has field ID as a parameter and therefore it is very easy to write code reacting to a change of a particular field. It is so easy that the modifiedField() method is often used even in such cases, when it really shouldn’t be used.

A typical (error) scenario looks like this: “If the value of field X in table A is changed, update field Y in table B to the same value. So I’ll call update of B from A.modifiedField().”

What’s wrong? Table B is updated, but table B is not yet. And it may never be updated. User can leave form without saving, a network failure may occur etc. The database integrity is corrupted and impacts of incorrect data may be… miscellaneous.

The origin of these errors is almost impossible to trace back in a database. On the other, it is usually easy prey for code review.

The correct aproach is to use modifiedField() for updates of the changing record (related fields filling, recalculations), but all changes in database must be in a transaction with the record saving. A code specific for a change of a particular field can be called in update() too (using a condition buffer.Field != buffer.orig().Field).