我的项目代码与此类似
@Transactional(readOnly = true)
public void tt() {
dd();
}
@Transactional()
public void dd() {
gg();
}
@Transactional(readOnly = true)
public void gg() {
}
函数dd由其他只读事务函数使用,而不是只读函数。假设事务应该从执行tt扩展到gg - dd中的操作是否为只读事务?
答案 0 :(得分:6)
在这个特定的例子中,你的问题没有实际意义。
dd()
对tt()
的调用不会通过代理边界,因此不会向dd()
应用任何事务建议(因为它是在同一实例内的调用)。与来自gg()
的{{1}}的来电相同。因此,只有从外部到dd()
的调用实际上是事务建议的(在您的情况下,使用tt()
)并且这将是将在整个调用链中使用的事务。
在一般情况下,请阅读@melihcelik暗示的文档 - 它解释了行为。
答案 1 :(得分:3)
如果您正在执行get / select并且没有进行任何更改,请使用@Transactional(readoOnly = true)
,这意味着不会应用任何锁定(这更有效)。
对于我使用的更新/插入/删除/保存/合并(当需要锁定时):
@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
答案 2 :(得分:3)
Spring的AbstractPlatformTransactionManager
有一个名为validateExistingTransaction
的属性来控制这种行为。 Javadoc说:
当参与现有交易时(例如,PROPAGATION_REQUIRES或PROPAGATION_SUPPORTS遇到现有交易),此外部交易的特征甚至将应用于内部交易范围。验证将检测内部事务定义上的不兼容隔离级别和只读设置,并通过抛出相应的异常来拒绝参与。
由于Spring @Transactional
注释的默认传播为REQUIRED
且默认验证策略为false,因此我希望Spring在只读模式下使用从tt
方法调用创建的现有事务。
如果您想要一个只读事务,那么您必须使用以下方法注释您的方法:
@Transactional(propagation=Propagation.REQUIRES_NEW, readOnly=true)