It seems quite unclear what transactional model is used within the Repository:
- apparently many beginTransaction() calls can be called one after another, and the Repo will keep track of current transaction depth
- when calling commit(), 2 different things happen:
+ the persistence layer commits regardless of transaction depth
+ only at depth 0 the commit events are fired
- when calling rollback(), 2 different things happen:
+ the persistence layer rolls back regardless of transaction depth
+ only the events tied to the current transaction depth are discarded
The main questions with this is: are nested transactions supported?
- it seems so, as there is the concept of a transaction depth
[EDIT *further tests seem to disprove the 3 bullet points below* ]
- however, the persistence layer does not allow stacked transactions. To call twice commit() is a fatal error. This means they will not work
- f.e. imagine a function X which uses a repo transaction in its body. Then a function Y which does call in order: $repo->beginTransaction(); X(); $repo->commit(); => a fatal error will ensue, as the db layer (doctrine) will not allow the 2nd commit to be executed
- if you go look at the logic of db transactions in eZ4, you will see that the db commit() was only called when the transaction depth was 0, and the above code worked
An ancillary question is: when rolling back, only the latest 'logical' transaction will be cancelled, whereas the db will in fact roll back all the way to the 1st begin-transaction call found. The latter behaviour is implemented by all databases afaik. This means that after a rollback() call from a nested transaction, the db will be out of transactions, whereas the repository will still think that it is in a transaction.
This is dangerous imho, and unexpected by developers who are familiar with transactions.
Wouldn't it make more sense to:
- only call the db commit() when the repo commit() is called and transaction depth is 0?
- always roll back to transaction depth 0 regardless of current transaction depth?
- (as an alternative, make sure that the db allows partial rollbacks?)
[EDIT *further tests seem to disprove as well the text below* ]
As a side note: Code which used to work in eZPublish 5 and does not work any more in eZPlatform:
- begin transaction
- become admin (in repo)
- edit stuff
- become anon again
- commit transaction
This worked because the 'transaction' was managed as a "db transaction". The repo user did not interfere with it.
In eZPlatform, some stuff is carried out post transaction commit.
If that 'stuff' includes e.g. clearing cache for a location that anon user can not read, then there is a fatal error, as cache clearing involves trying to access the location...