def _finish_store(self): """Move stored objects from the temporary table to final storage. Returns a list of (oid, tid) to be received by Connection._handle_serial(). """ assert self._tid is not None cursor = self._store_cursor adapter = self._adapter cache = self._cache # Detect conflicting changes. # Try to resolve the conflicts. resolved = set() # a set of OIDs while True: conflict = adapter.mover.detect_conflict(cursor) if conflict is None: break oid_int, prev_tid_int, serial_int, data = conflict oid = p64(oid_int) prev_tid = p64(prev_tid_int) serial = p64(serial_int) rdata = self.tryToResolveConflict(oid, prev_tid, serial, data) if rdata is None: # unresolvable; kill the whole transaction raise POSException.ConflictError( oid=oid, serials=(prev_tid, serial), data=data) else: # resolved data = rdata self._adapter.mover.replace_temp( cursor, oid_int, prev_tid_int, data) resolved.add(oid) cache.store_temp(oid_int, data) # Move the new states into the permanent table tid_int = u64(self._tid) serials = [] if self.blobhelper is not None: txn_has_blobs = self.blobhelper.txn_has_blobs else: txn_has_blobs = False oid_ints = adapter.mover.move_from_temp(cursor, tid_int, txn_has_blobs) for oid_int in oid_ints: oid = p64(oid_int) if oid in resolved: serial = ConflictResolution.ResolvedSerial else: serial = self._tid serials.append((oid, serial)) return serials