b29a268b1d
- Move completed plan files to .plans/done/ - Move 18 open plan files to .plans/open/ - Update .gitignore to exclude .verified_plans temp file - Verified all 18 open plans still describe unimplemented issues
1.7 KiB
1.7 KiB
Issue #203: Missing Database Transactions in MemberService
Problem
The MemberService::create() method inserts a member and its sub-entities (addresses, phones, emails) in separate queries without a transaction:
public function create(array $data, array $addresses = [], ...): array {
// ...
$member = $this->memberMapper->insert($member);
$savedAddresses = $this->saveAddresses($member->getId(), $addresses);
$savedPhones = $this->savePhones($member->getId(), $phones);
$savedEmails = $this->saveEmails($member->getId(), $emails);
// ...
}
If savePhones() fails, the member is created but phones are not attached.
Similarly, softDelete() deletes sub-entities separately without a transaction.
Impact
- Data inconsistency if partial failures occur
- Orphaned sub-entities on failed member creation
- Orphaned member on failed sub-entity creation
Solution
Wrap the operation in a transaction:
use OCP\DB\Events\SQLFileEmitter;
public function create(array $data, ...): array {
$this->db->beginTransaction();
try {
$member = $this->memberMapper->insert($member);
$savedAddresses = $this->saveAddresses($member->getId(), $addresses);
// ...
$this->db->commit();
} catch (\Exception $e) {
$this->db->rollback();
throw $e;
}
}
Tasks
- Add transaction wrapping to
MemberService::create() - Add transaction wrapping to
MemberService::softDelete() - Add transaction wrapping to
MemberService::update()(sync operations) - Verify rollback works correctly on failure
- Consider adding a
DbTransactionTraitfor reusability
Labels
- bug
- backend
- priority:high
- data-integrity