创建一系列依赖操作,并在其中一个操作失败时回滚所有操作
saga_p的Python项目详细描述
创建一系列依赖操作,并在其中一个操作失败时回滚所有操作。
安装
$ pip install saga_py
用法
简单示例
fromsagaimportSagaBuildercounter1=0counter2=0defincr_counter1(amount):globalcounter1counter1+=amountdefincr_counter2(amount):globalcounter2counter2+=amountdefdecr_counter1(amount):globalcounter1counter1-=amountdefdecr_counter2(amount):globalcounter2counter2-=amountSagaBuilder \ .create() \ .action(lambda:incr_counter1(15),lambda:decr_counter1(15)) \ .action(lambda:incr_counter2(1),lambda:decr_counter2(1)) \ .action() \ .build() \ .execute()# if every action succeeds, the effects of all actions are appliedprint(counter1)# 15print(counter2)# 1
操作失败示例
如果一个操作失败,将运行对所有已执行操作的补偿,并引发一个sagaerror来包装 运行期间遇到的所有异常。
fromsagaimportSagaBuilder,SagaErrorcounter1=0counter2=0defincr_counter1(amount):globalcounter1counter1+=amountdefincr_counter2(amount):globalcounter2counter2+=amountraiseBaseException('some error happened')defdecr_counter1(amount):globalcounter1counter1-=amountdefdecr_counter2(amount):globalcounter2counter2-=amounttry:SagaBuilder \ .create() \ .action(lambda:incr_counter1(15),lambda:decr_counter1(15)) \ .action(lambda:incr_counter2(1),lambda:decr_counter2(1)) \ .action() \ .build() \ .execute()exceptSagaErrorase:print(e)# wraps the BaseException('some error happened')print(counter1)# 0print(counter2)# 0
动作和补偿失败示例
因为action2的补偿失败了,所以从框架的角度来看补偿效果是不确定的, 所有其他补偿都不考虑。
fromsagaimportSagaBuilder,SagaErrorcounter1=0counter2=0defincr_counter1(amount):globalcounter1counter1+=amountdefincr_counter2(amount):globalcounter2counter2+=amountraiseBaseException('some error happened')defdecr_counter1(amount):globalcounter1counter1-=amountdefdecr_counter2(amount):globalcounter2raiseBaseException('compensation also fails')try:SagaBuilder \ .create() \ .action(lambda:incr_counter1(15),lambda:decr_counter1(15)) \ .action(lambda:incr_counter2(1),lambda:decr_counter2(1)) \ .action() \ .build() \ .execute()exceptSagaErrorase:print(e)#print(counter1)# 0print(counter2)# 1
将值从一个操作传递到下一个操作
操作可以返回返回值的dict。 然后,dict作为关键字参数传递给下一个操作,并得到相应的补偿。 补偿之间不能传递任何值。
fromsagaimportSagaBuilder,SagaErrorcounter1=0counter2=0defincr_counter1(amount):globalcounter1counter1+=amountreturn{'counter1_value':counter1}defincr_counter2(counter1_value):globalcounter2counter2+=amountdefdecr_counter1(amount):globalcounter1counter1-=amountdefdecr_counter2(counter1_value):globalcounter2counter2-=amountSagaBuilder \ .create() \ .action(lambda:incr_counter1(15),lambda:decr_counter1(15)) \ .action(incr_counter2,decr_counter2) \ .action() \ .build() \ .execute()print(counter1)# 15print(counter2)# 15