45 lines
1.2 KiB
Python
45 lines
1.2 KiB
Python
|
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 = set()
|
||
|
# child classes should set this to a JSON-serializable object
|
||
|
# once they are finished
|
||
|
self.result = None
|
||
|
|
||
|
def finish(self, result):
|
||
|
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.add(operation)
|
||
|
yield operation
|
||
|
|
||
|
def execute(self):
|
||
|
"""Execute the transaction synchronously."""
|
||
|
for _ in self.execute_iter():
|
||
|
pass
|
||
|
|
||
|
@abstractmethod
|
||
|
def rollback(self):
|
||
|
"""Roll back the transaction, when it fails."""
|
||
|
raise NotImplementedError()
|