# 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: ```php 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: ```php 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 `DbTransactionTrait` for reusability ## Labels - bug - backend - priority:high - data-integrity