通过 spring 注释进行事务 - 只读或非只读?

发布于 2024-12-18 06:03:32 字数 285 浏览 3 评论 0原文

我的项目代码类似于此

@Transactional(readOnly = true)
public void tt() {
    dd();
}

@Transactional()
public void dd() {
    gg();
}

@Transactional(readOnly = true)
public void gg() {

}

函数 dd 既被其他只读事务函数使用,也被只读函数使用。假设事务应该从 tt 的执行扩展到 gg - dd 中的操作是否是只读事务?

I've got in my project code similar to this

@Transactional(readOnly = true)
public void tt() {
    dd();
}

@Transactional()
public void dd() {
    gg();
}

@Transactional(readOnly = true)
public void gg() {

}

Function dd is used both by other readonly transaction functions and not readonly functions. Assuming that transaction should extendend from execution of tt to gg - operations in dd will in be read-only transaction or not?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

带刺的爱情 2024-12-25 06:03:32

在这个特定的例子中,你的问题没有实际意义。

tt() 调用 dd() 不会通过代理边界,因此不会向 dd() 应用事务建议(因为这是同一实例内的调用)。与从 dd() 调用 gg() 相同。因此,只有从外部对 tt() 的调用实际上才是交易建议的(在您的情况下,使用 readOnly=true),并且这将是交易在整个调用链中使用。

但在一般情况下,请阅读 @melihcelik 暗示的文档 - 它解释了该行为。

In this particular example, your question is moot.

The call to dd() from tt() will not pass the proxy boundary so no transactional advise will be applied to dd() (since it's a call inside the same instance). Same with the call to gg() from dd(). Consequently, only the call from outside to tt() would actually be transaction-advised (in your case, with readOnly=true) and that would be the transaction that would be used in the entire call-chain.

In the general case though, read the documentation hinted by @melihcelik - it explains the behavior.

闻呓 2024-12-25 06:03:32

Spring 的 AbstractPlatformTransactionManager 有一个名为 validateExistingTransaction 的属性来控制此行为。 Javadoc 指出:

当参与现有事务时(例如,使用 PROPAGATION_REQUIRES 或 PROPAGATION_SUPPORTS 遇到现有事务),该外部事务的特征甚至将适用于内部事务范围。验证将检测内部事务定义上不兼容的隔离级别和只读设置,并通过抛出相应的异常来拒绝参与。

由于 Spring @Transactional 注释的默认传播是 REQUIRED 并且默认验证策略为 false,我希望 Spring 使用从 tt 方法调用创建的现有事务处于只读模式。

如果你想要一个只读事务,那么你必须用以下方式注释你的方法:

  @Transactional(propagation=Propagation.REQUIRES_NEW, readOnly=true)

Spring's AbstractPlatformTransactionManager has a property named validateExistingTransaction that controls this behavior. Javadoc states that:

When participating in an existing transaction (e.g. with PROPAGATION_REQUIRES or PROPAGATION_SUPPORTS encountering an existing transaction), this outer transaction's characteristics will apply even to the inner transaction scope. Validation will detect incompatible isolation level and read-only settings on the inner transaction definition and reject participation accordingly through throwing a corresponding exception.

Since default propagation for Spring @Transactional annotation is REQUIRED and default validation strategy is false, I expect Spring to use existing transaction created from tt method call in readonly mode.

If you want to have a read only transaction, then you have to annotate your method with:

  @Transactional(propagation=Propagation.REQUIRES_NEW, readOnly=true)
失去的东西太少 2024-12-25 06:03:32

如果您正在执行 get/select 并且不进行任何更改,请使用@Transactional(readoOnly = true) ,这意味着不会应用任何锁(这更有效)。

对于更新/插入/删除/保存/合并,我使用(当需要锁时):

@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)

use @Transactional(readoOnly = true) if you are performing a get/select and not making any changes, this means that no locks will be applied (which is more efficent).

For updates/inserts/deletions/saves/merges I use (when a lock is required) :

@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文