最新测试结果 start...:
ahuaxuan 在回复中说的没错,在DataSourceUtils.prepareConnectionForTransaction(con, definition)中的确会设置readonly,我之前说的DataSourceTransactionManager中不设置readonly的说法是错误的。
但在oracle下,这个readonly确实有问题,我一步步测下来,原因就是出在 con.setAutoCommit(false) 这行代码上:
1. 如果 con.setReadOnly(true) 放在 con.setAutoCommit(false) 前面,就是代码现在的做法,readonly是不起作用的。
2. 反之,如果我把DataSourceUtils.prepareConnectionForTransaction(con, definition) 代码放在它的后面的时候,readonly 起了作用。
难道oracle的驱动对这个顺序还有影响吗,有点匪夷所思啊。
不知道在其他数据库中有没有影响。
//其中, DataSourceUtils.prepareConnectionForTransaction(con, definition)中会设置con.setReadOnly(true)
protected void doBegin(Object transaction, TransactionDefinition definition) {
....
....
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
txObject.setPreviousIsolationLevel(previousIsolationLevel);
// Switch to manual commit if necessary. This is very expensive in some JDBC drivers,
// so we don't want to do it unnecessarily (for example if we've explicitly
// configured the connection pool to set it already).
if (con.getAutoCommit()) {
txObject.setMustRestoreAutoCommit(true);
if (logger.isDebugEnabled()) {
logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
}
con.setAutoCommit(false);
}
...
...
}
最新测试结果 end...
为何readonly不起作用,有人真正测过吗?
环境
1. spring2.5 + ibatis/jdbctemplate(测了这两个) + oracle10,
2. 驱动ojdbc14.jar
3. 连接池 dbcp和c3p0都测了。
先看部分后台,证明调用的方法确实开启了readonly:
21/01/2009 16:43:01,457 <DEBUG> (org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource)- Adding transactional method [search*] with attribute [PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly]
21/01/2009 17:10:00,864 <DEBUG> (org.springframework.jdbc.datasource.DataSourceTransactionManager)- Creating new transaction with name [com.me.service.logic.ViewService.searchLeave]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly
先在oracle里面测试下
set transaction read only;
update stu set title = 'oh,god' where id='12345'
抛错,证明oracle对read only有效:
ORA-01456: may not perform insert/delete/update operation inside a READ ONLY transaction
程序中的配置
<aop:config>
<aop:pointcut id="serviceOperation"
expression="execution(* com.me.service.logic.*ServiceImpl.*(..))" />
<aop:advisor pointcut-ref="serviceOperation" advice-ref="txAdvice" />
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="search*" read-only="true" />
</tx:attributes>
</tx:advice>
//ViewServiceImpl:
public List searchLeave(Leave leave) {
//update stu set title = 'oh,god' where id='12345'
int j = viewDAO.updateStu();
return viewDAO.searchLeave(leave);
}
以上的searchLeave方法应该抛出错误的。readonly不允许update。
但一切似乎都没有效果。
分享到:
相关推荐
本知识点将深入探讨Spring中的事务管理,主要包括事务的传播特性、隔离级别以及readonly属性。 1. 事务的传播特性: 在Spring中,事务的传播特性定义了在一个事务方法被另一个事务方法调用时,应该如何处理事务...
Spring事务原理是指Spring框架中的一种机制,用于管理事务,并提供了多种配置方式。事务是指一系列的操作,作为一个整体执行,如果其中某个操作失败,整个事务将回滚。Spring事务原理围绕着两个核心:...
在Spring 1.x中,声明式事务有两种主要的配置方式,第一种是通过XML配置逐个为每个业务类创建事务代理。首先,你需要声明一个事务管理器,如`HibernateTransactionManager`,然后定义业务层的bean,并为其创建一个...
这种方式灵活性较高,但会导致代码中事务管理的逻辑过于耦合,不易维护。在Spring中,可以使用`@Transactional`注解的`propagation`属性配合`TransactionTemplate`进行更安全的编程式事务管理。 2. **声明式事务...
在Spring中,事务配置主要涉及到三个核心组件:DataSource、TransactionManager和代理机制。下面将详细介绍Spring的五种事务配置方式。 1. **基于XML的事务配置** - **每个Bean都有一个代理**: 在这种配置方式中...
总的来说,掌握 Spring 事务管理的五种配置方式,有助于我们在开发中更好地控制事务边界,保证数据的一致性和完整性。理解并灵活运用这些知识,能够提升我们的代码质量,降低系统风险,提高系统的稳定性和可靠性。
本篇文章将详细探讨Spring中的三种事务管理方式:编程式事务管理、声明式事务管理和基于注解的事务管理。 首先,编程式事务管理是通过编码来控制事务的开始、提交、回滚等操作。Spring提供了...
在Spring中,我们可以配置事务的传播行为,比如REQUIRED(默认,如果当前存在事务,则加入当前事务,否则新建一个事务)、PROPAGATION_SUPPORTS(如果当前存在事务,则加入,否则不开启事务)、PROPAGATION_REQUIRES...
在深入探讨Spring事务代理配置之前,我们先简要回顾一下Spring...通过以上步骤,我们就可以在Spring中成功配置事务代理,使得应用程序中的业务方法能够自动进行事务管理,极大地提高了代码的可维护性和事务的一致性。
在Spring中,事务管理通常分为三部分:DataSource、TransactionManager和代理机制。DataSource是数据源,TransactionManager是事务管理器,而代理机制则是实现事务控制的关键。 1. **基于XML的AOP代理配置** 这是...
Spring 事务管理是其核心特性之一,用于确保在执行数据库操作时的一致性和可靠性。它提供了五种不同的配置方式来适应不同的应用场景。以下是对这些配置方式的详细解释: 1. **基于代理的事务管理(Proxy-based ...
注解中可以包含多个属性,如`value`(指定事务管理器)、`propagation`(事务传播行为)、`isolation`(事务隔离级别)、`readOnly`(是否只读事务)等,以定制事务的行为。 3. **事务传播行为** 事务传播行为定义...
在本文中,我们将以JDBC事务管理为例,详细介绍Spring的事务管理机制。 Spring事务管理机制 Spring的事务管理机制是基于PlatformTransactionManager接口的实现的,该接口定义了三个方法:getTransaction、commit...
Spring 事务管理是Java开发中的核心概念,尤其是在企业级应用中,它确保了数据的完整性和一致性。在Spring框架中,事务管理通过实现ACID(原子性、一致性、隔离性和持久性)属性来保证数据库操作的正确性。 **原子...
在Spring中,可以设置`readOnly=true`,告知事务管理器该事务不需要修改数据。 接下来,我们看看两种事务配置方式: - **基于注解的事务管理**:这是Spring 2.5引入的新特性,通过在方法上使用`@Transactional`...
在Spring中,`@Transactional`注解可以设置多个属性,如`propagation`(事务传播行为),`isolation`(事务隔离级别),`timeout`(事务超时时间),`readOnly`(是否只读事务)和`rollbackFor`/`noRollbackFor`...
在Spring中,我们可以使用XML配置文件来声明事务,但更常见的是通过Java注解来完成。这里我们将重点讨论Annotation注解方式。主要涉及的注解有`@Transactional`,`@Rollback`以及`@Transactional(propagation=...
在Spring中,事务传播行为有七种,包括REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER和NESTED。每种行为都对应不同的事务处理策略,比如REQUIRED是默认行为,意味着如果当前存在事务,则加入...
声明式事务管理是Spring中非常受欢迎的特性,因为它允许开发者在不编写任何事务控制代码的情况下,通过配置来管理事务。这种方式使得事务管理与业务逻辑解耦,提高了代码的可维护性。 #### 基于注解的声明式事务...