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