Spring @Transactional 只读传播 [英] Spring @Transactional read-only propagation

查看:26
本文介绍了Spring @Transactional 只读传播的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用命令模式来允许我的 web 层在单个事务的上下文中使用 Hibernate 实体(从而避免延迟加载异常).然而,我现在对如何处理交易感到困惑.

I'm experimenting with using the command pattern to allow my web layer to work with Hibernate entities within the context of a single transaction (thus avoiding lazy loading exceptions). I am, however, confused now with how I should deal with transactions.

我的命令调用使用 @Transactional 注释注释的服务层方法.其中一些服务层方法是只读的 - 例如@Transactional(readOnly = true) - 有些是读/写的.

My commands call service layer methods that are annotated with @Transactional annotations. Some of these service layer methods are read-only - e.g. @Transactional(readOnly = true) - and some are read/write.

我的服务层公开了一个命令处理程序,用于执行代表 Web 层传递给它的命令.

My service layer exposes a command handler that executes commands passed to it on behalf of the web layer.

@Transactional
public Command handle(Command cmd) throws CommandException

我认为我将命令处理程序的 handle 方法设为事务性是正确的.这就是混淆的地方.如果一个命令的实现调用多个服务层方法,则命令处理程序无法知道命令中调用的操作是只读、读/写还是组合两个.

I assume I am right in making the command handler's handle method transactional. This is where the confusion comes in. If the implementation of a command makes calls to multiple service layer methods, there is no way for the command handler to know whether operations called within the command will be read-only, read/write or a combination of the two.

我不明白这个例子中的传播是如何工作的.如果我要使 handle() 方法 readOnly = true,那么如果该命令调用使用 @Transactional( 注释的服务层方法),会发生什么realOnly = false)?

I don't understand how propagation works in this example. If I were to make the handle() method readOnly = true, then what happens if the command then calls a service layer method that is annotated with @Transactional(realOnly = false)?

推荐答案

首先,由于 Spring 本身并不做持久化,它无法指定 readOnly 的确切含义.这个属性只是对提供者的一个提示,行为取决于,在这种情况下,Hibernate.

First of all, since Spring doesn't do persistence itself, it cannot specify what readOnly should exactly mean. This attribute is only a hint to the provider, the behavior depends on, in this case, Hibernate.

如果您指定 readOnlytrue,则刷新模式将设置为 FlushMode.NEVER 在当前休眠会话阻止会话提交事务.

If you specify readOnly as true, the flush mode will be set as FlushMode.NEVER in the current Hibernate Session preventing the session from committing the transaction.

此外,还会在JDBC Connection上调用setReadOnly(true),这也是对底层数据库的一个提示.如果您的数据库支持它(很可能支持),这与 FlushMode.NEVER 的效果基本相同,但它更强大,因为您甚至无法手动刷新.

Furthermore, setReadOnly(true) will be called on the JDBC Connection, which is also a hint to the underlying database. If your database supports it (most likely it does), this has basically the same effect as FlushMode.NEVER, but it's stronger since you cannot even flush manually.

现在让我们看看事务传播是如何工作的.

Now let's see how transaction propagation works.

如果您没有明确地将 readOnly 设置为 true,您将拥有读/写事务.根据事务属性(例如 REQUIRES_NEW),有时您的事务会在某个时刻暂停,然后启动一个新事务并最终提交,然后恢复第一个事务.

If you don't explicitly set readOnly to true, you will have read/write transactions. Depending on the transaction attributes (like REQUIRES_NEW), sometimes your transaction is suspended at some point, a new one is started and eventually committed, and after that the first transaction is resumed.

好的,我们快到了.让我们看看是什么将 readOnly 带入了这个场景.

OK, we're almost there. Let's see what brings readOnly into this scenario.

如果读/写事务中的方法调用需要只读事务的方法,第一个应该挂起,否则会发生刷新/提交在第二种方法的末尾.

If a method in a read/write transaction calls a method that requires a readOnly transaction, the first one should be suspended, because otherwise a flush/commit would happen at the end of the second method.

相反,如果您从需要读/写只读事务中调用方法,同样,第一个将被挂起,因为它不能被刷新/提交,第二种方法需要.

Conversely, if you call a method from within a readOnly transaction that requires read/write, again, the first one will be suspended, since it cannot be flushed/committed, and the second method needs that.

readOnly-to-readOnlyread/write-to-read/write 情况下,不需要暂停外部事务(除非您显然,否则指定传播).

In the readOnly-to-readOnly, and the read/write-to-read/write cases the outer transaction doesn't need to be suspended (unless you specify propagation otherwise, obviously).

这篇关于Spring @Transactional 只读传播的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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