from abc import ABC, abstractmethod class AbstractTransaction(ABC): """Represents an atomic group of operations.""" # child classes should override this operations = [] def __init__(self): self.finished_operations = [] # child classes should set this to a JSON-serializable object # once they are finished self.result = None def finish(self, result): """ Store a result in this object so that it can be returned to the client. """ self.result = result @abstractmethod def child_execute_iter(self): """ Template Method design pattern. To be implemented by child classes. Every time an operation is completed, it should be yielded. """ raise NotImplementedError() def execute_iter(self): """ Execute the transaction, yielding an operation each time one is completed. """ for operation in self.child_execute_iter(): self.finished_operations.append(operation) yield operation def execute(self): """Execute the transaction synchronously.""" for _ in self.execute_iter(): pass def rollback(self): """ Roll back the transaction, when it fails. If the transaction only has one operation, then there is no need to implement this. """ pass