交易传播的现实生活场景 [英] Real life scenarios for Transaction propagations

查看:53
本文介绍了交易传播的现实生活场景的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有各种交易传播,比如

REQUIRED - 这是 DML 操作的情况.

REQUIRED - This is the case for DML operation.

SUPPORTS - 这是查询数据库的情况.

SUPPORTS - This is the case for querying database.

MANDATORY - ?
REQUIRES_NEW - ?
NOT_SUPPORTED - ?
NEVER - ?
NESTED - ?

这些交易传播有哪些现实生活场景?为什么这些非常适合这种情况?

What are some real life scenarios for these transaction propagations? Why these are perfect fit into that situation?

推荐答案

用法多种多样,没有简单的答案,但我会尽量解释得最清楚

There are various usages and there is no simple answer but I'll try to be the most explainatory

  • MANDATORY(期望交易):通常用于您期望任何更高上下文"层启动交易并且您只想在其中继续.例如,如果您想要从 HTTP 请求到响应的整个操作的一个事务.然后在 JAX-RS 资源级别启动事务,较低层(服务)需要事务在其中运行(否则会引发异常).
  • REQUIRES_NEW(始终创建新事务):这会创建一个新事务并暂停当前存在的事务.例如,从上面的示例中,这是您在 JAX-RS 资源上设置的级别.或者通常情况下,如果您的流程以某种方式发生变化,并且您想将您的逻辑拆分为多个事务(因此您的代码具有应该分开的多个逻辑操作).
  • REQUIRED(在需要时继续事务或创建):MANDATORY 和 REQUIRES_NEW 之间的某种混合.在 MANDATORY 中,您希望事务存在,对于此级别,您希望它存在,如果不存在,则创建它.通常用于类似 DAO 的服务(根据我的经验),但这实际上取决于您应用的逻辑.
  • SUPPORTS(调用者决定是否不在/在事务中运行):如果想使用与调用者相同的上下文(更高的上下文),如果你的调用者在事务中运行,那么你运行也.如果没有,你也是非交易性的.如果您需要更高的上下文来决定,也可以在类似 DAO 的服务中使用.
  • NESTED(子事务):我必须承认我没有在实际代码中使用这个,但通常你会创建一个真正的子事务,作为某种检查点.因此,它在父"事务的上下文中运行,但如果失败,则返回到该检查点(嵌套事务的开始).当您在应用程序中需要这种逻辑时,这可能很有用,例如,如果您想向数据库中插入大量项目,提交有效项目并跟踪无效项目(因此您可以在嵌套事务失败时捕获异常但仍然可以为有效的交易提交整个交易)
  • NEVER(期望没有事务):当您想确保根本不存在事务时就是这种情况.如果在事务中运行的某些代码到达此代码,则会引发异常.所以通常这适用于与 MANDARTORY 完全相反的情况.例如.当您知道此代码不应影响任何事务时 - 很可能是因为该事务不应该存在.
  • NOT_SUPPORTED(非事务性继续):这比 NEVER 弱,您希望代码以非事务性方式运行.如果您以某种方式从事务所在的上下文中输入此代码,则会暂停此事务并以非事务方式继续.
  • MANDATORY (expecting transaction): Typically used when you expect that any "higher-context" layer started the transaction and you only want to continue in it. For example if you want one transaction for whole operation from HTTP request to response. Then you start transaction on JAX-RS resource level and lower layers (services) require transaction to run within (otherwise exception is thrown).
  • REQUIRES_NEW (always create new transaction): This creates a new transaction and suspends the current one if any exists. From above example, this is the level you set on your JAX-RS resource for example. Or generally if your flow somehow changes and you want to split your logic into multiple transactions (so your code have mutliple logic operations that should be separated).
  • REQUIRED (continue in transaction or create if needed): Some kind of mix between MANDATORY and REQUIRES_NEW. In MANDATORY you expect that the transaction exists, for this level you hope that it exists and if not, you create it. Typically used in DAO-like services (from my experience), but it really depends on logic of your app.
  • SUPPORTS (caller decides whether to not/run in transaction): Used if want to use the same context as caller (higher context), if your caller was running in transaction, then you run in too. If it didn't, you are also non-transactional. May also be used in DAO-like services if you want higher context to decide.
  • NESTED (sub-transaction): I must admit I didn't use this one in real code but generally you create a real sub-transaction that works as some kind of checkpoint. So it runs in the context of "parent" transaction but if it fails it returns to that checkpoint (start of nested transaction). This may be useful when you require this kind of logic in your application, for example if you want to insert large number of items to the database, commiting valid ones and keeping track of invalid ones (so you can catch exception when nested transaction fails but can still commit the whole transaction for valid ones)
  • NEVER (expecting there is no transaction): This is the case when you want to be sure that no transaction exists at all. If some code that runs in transaction reaches this code, exception is thrown. So typically this is for cases completely opposite to MANDARTORY. E.g. when you know that no transaction should be affected by this code - very likely because the transaction should not exist.
  • NOT_SUPPORTED (continue non-transactionally): This is weaker than NEVER, you want the code to be run non-transactionally. If somehow you enter this code from context where transaction is, you suspend this transaction and continue non-transactionally.

根据我的经验,您经常希望一项业务操作具有原子性.因此,每个请求只需要一个事务/...例如,通过 HTTP 进行简单的 REST 调用,在一个类似 HTTP 的事务中执行一些数据库操作.因此,我的典型用法是在顶级(JAX-RS 资源)上REQUIRES_NEW,在注入到此资源(甚至更低)的所有低级服务上MANDATORY.

From my experience, you very often want one business action to be atomic. Thus you want only one transaction per request/... For example simple REST call via HTTP that does some DB operations all in one HTTP-like transaction. So my typical usage is REQUIRES_NEW on the top level (JAX-RS Resource) and MANDATORY on all lower level services that are injected to this resource (or even lower).

这可能对您有用.它描述了代码在给定传播(调用者->方法)下的行为

This may be useful for you. It describes how code behave with given propagation (caller->method)

  • 必需:无->T1、T1->T1
  • REQUIRES_NEW:无->T1、T1->T2
  • 强制性:无->例外,T1->T1
  • NOT_SUPPORTED:无->无,T1->无
  • 支持:无->无,T1->T1
  • 从不:无->无,T1->例外
  • REQUIRED: NONE->T1, T1->T1
  • REQUIRES_NEW: NONE->T1, T1->T2
  • MANDATORY: NONE->Exception, T1->T1
  • NOT_SUPPORTED: NONE->NONE, T1->NONE
  • SUPPORTS: NONE->NONE, T1->T1
  • NEVER: NONE->NONE, T1->Exception

这篇关于交易传播的现实生活场景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆