This is somewhat related to IDEMPIERE-4286.
In adempiere times a practice was introduced to add getters from cache with trx, some of those getter methods even change the trx of the object recovered from cache (not verifying if the object is fresh as in theory it can be reading a stale object different from the one in DB).
Although the incidence of problems caused by this is low (and probably this is why this has not been reported or tackled) - in heavy usage environments the occurrences must be more frequent, and probably reviewed like different errors (like working on a closed transaction, or writing stale data to the database, or db locks because of competing transactions).
This ticket is to evaluate the possibilities and try to get a good solution for this.
has suggested that cache objects must be read-only.
Maybe we could implement a way to enforce that in code - add some isFromCache or isReadOnly property in PO object and forbidding to save/delete those objects.
That change can impact a lot of core processes and plugins, so it would require extensive tests. That means the developer must be very conscious about when requiring a r/o object is preferably to use cache (performance wise), but when requiring a r/w object must read it from database probably using a constructor, and maybe even as a best practice we can enforce the usage of transactions on r/w objects.