2011-11-24 85 views
1

我有我的项目代码与此类似通过春季注释进行交易 - 只读还是不行?

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

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

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

} 

功能的DD都是由其他只读交易功能,而不是只读功能使用。假设事务应该从tt执行到gg - dd中的操作将是只读事务或不是?

回答

3

Spring的AbstractPlatformTransactionManager有一个名为validateExistingTransaction控制这种行为特性。 Javadoc中指出:

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

由于春季@Transactional注释默认传播是REQUIRED和默认的验证策略是假的,我希望Spring使用现有的以只读模式tt方法调用创建的事务。

如果你想有一个只读事务,那么你有注释的方法:

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

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

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

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

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

dd()tt()的调用将不会通过代理边界,因此没有交易建议将应用于dd()(因为它是在同一实例内的调用)。与拨打电话gg()dd()一样。因此,只有从外部拨打tt()的电话实际上是交易建议的(在您的情况下为readOnly=true),并且这将是整个呼叫链中将使用的交易。

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