It used to lock only the target element. It now default locks all the three components (the two sources and the target) so expect them to be real objects, but it can be asked to have a different behavior through it's 'flags' field.
In the 'flags' field, bit 0 means lock the first source, bit 1 means lock the second one, and bit 2 means lock the target, so setting flags to 4 will provide the old behavior.

The source of the 'Relation' data type is available in relation.c

The trouble with the old implementation is that it could lead to awful bugs:
If you create a type in a module, then free the module, the type will be freed. Now, if you used the Pointer to that type or Array of that type, they are recorded in the pointers or arrays relations, so there is a wrong element in these. If you then create new types, then one could be created at the exact same address of the freed one, so there would be a clash in the relation. Also it never happened, it was a sad design.
On the other hand, the trouble with the new implementation is that it may prevent some objects to get freed, but this is a more common, and not fatal trouble (even garbage collectors have so troubles).