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

查看:165
本文介绍了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)?

希望您能对此有所了解,并欢迎您发表评论...

I'd appreciate a better understanding of this and welcome your comments...

安德鲁

推荐答案

首先,由于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.

如果将readOnly指定为true,则刷新模式将在当前的休眠会话中设置为 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连接上调用 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.

如果 read/write 事务中的方法调用需要 readOnly 事务的方法,则第一个应暂停,因为否则将发生刷新/提交在第二种方法的结尾.

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.

相反,如果您从需要 read/write readOnly 事务中调用方法,则第一个方法将被挂起,因为无法刷新/提交,第二种方法需要它.

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-readOnly read/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天全站免登陆