您的位置:首页 > 编程语言 > Java开发

Spring read-only="true" 只读事务的一些概念

2017-11-23 11:09 633 查看
概念:从这一点设置的时间点开始(时间点a)到这个事务结束的过程中,其他事务所提交的数据,该事务将看不见!(查询中不会出现别人在时间点a之后提交的数据)


应用场合:

如果你一次执行单条查询语句,则没有必要启用事务支持,数据库默认支持SQL执行期间的读一致性;

如果你一次执行多条查询语句,例如统计查询,报表查询,在这种场景下,多条查询SQL必须保证整体的读一致性,否则,在前条SQL查询之后,后条SQL查询之前,数据被其他用户改变,则该次整体的统计查询将会出现读数据不一致的状态,此时,应该启用事务支持。

【注意是一次执行多次查询来统计某些信息,这时为了保证数据整体的一致性,要用只读事务】

怎样设置:

对于只读查询,可以指定事务类型为readonly,即只读事务。

由于只读事务不存在数据的修改,因此数据库将会为只读事务提供一些优化手段,例如Oracle对于只读事务,不启动回滚段,不记录回滚log。

(1)在JDBC中,指定只读事务的办法为: connection.setReadOnly(true);

(2)在Hibernate中,指定只读事务的办法为: session.setFlushMode(FlushMode.NEVER);

此时,Hibernate也会为只读事务提供Session方面的一些优化手段

(3)在Spring的Hibernate封装中,指定只读事务的办法为: bean配置文件中,prop属性增加“readOnly”

或者用注解方式@Transactional(readOnly=true)

【 if the transaction is marked as read-only, Spring will set the Hibernate Session’s flush mode to FLUSH_NEVER,

and will set the JDBC transaction to read-only】也就是说在Spring中设置只读事务是利用上面两种方式

在将事务设置成只读后,相当于将数据库设置成只读数据库,此时若要进行写的操作,会出现错误

//测试get开头的只读属性,写数据会保错的情况
public Object getDemoTestTransaction() {
TOmOrderPlaneItemExample example = new TOmOrderPlaneItemExample();
example.createCriteria().andOrderCodeEqualTo("422751536598089068544");
List<TOmOrderPlaneItem> selectByExample = tOmOrderPlaneItemMapper.selectByExample(example );
TOmOrderPlaneItem record = new TOmOrderPlaneItem();
record.setOrderCode("123");
record.setPaymentMode("1");
tOmOrderPlaneItemMapper.insert(record );
return selectByExample;
}


单元测试:

@Test
public void test_Transaction() {
Object demoTestTransaction = planeService.getDemoTestTransaction();
log.debug("===="+JSON.toJSONString(demoTestTransaction));
}


贴一段配置事务的xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> 
<tx:annotation-driven transaction-manager="transactionManager"/>
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
<aop:config>
<aop:pointcut id="ServiceMethods"
expression="execution(* com.baidu.business.service..*Service.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="ServiceMethods"/>
</aop:config>

<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="query*" read-only="true"/>
<tx:method name="count*" read-only="true"/>
<tx:method name="select*" read-only="true"/>
<tx:method name="search*" read-only="true"/>
<tx:method name="has*" read-only="true"/>
<tx:method name="export*" read-only="true"/>
<tx:method name="is*" read-only="true"/>
<tx:method name="*" propagation="REQUIRED" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>

</beans>

注意以get、find开头的字段,都是可读的,也可以通过@Transactional(readOnly = false) 来覆盖掉配置文件的属性,这样就能插入数据了




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: