zoukankan      html  css  js  c++  java
  • Spring read-only="true" 只读事务的

    概念:从这一点设置的时间点开始(时间点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) 来覆盖掉配置文件的属性,这样就能插入数据了

     ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    <tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
               <!-- 读取操作 -->
    <tx:method name="load*" propagation="REQUIRED" isolation="DEFAULT" read-only="true"/>
    <tx:method name="get*" propagation="REQUIRED" isolation="DEFAULT" read-only="true"/>
    <tx:method name="find*" propagation="REQUIRED" isolation="DEFAULT" read-only="true"/>
    </tx:attributes>
    </tx:advice>

    spring中PROPAGATION类的事务属性详解

     

    1. PROPAGATION_REQUIRED:         支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 

    2. PROPAGATION_SUPPORTS:         支持当前事务,如果当前没有事务,就以非事务方式执行。 

    3. PROPAGATION_MANDATORY:      支持当前事务,如果当前没有事务,就抛出异常。 

    4. PROPAGATION_REQUIRES_NEW:   新建事务,如果当前存在事务,把当前事务挂起。

    5.  PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 

    6. PROPAGATION_NEVER:               以非事务方式执行,如果当前存在事务,则抛出异常。 

    7. PROPAGATION_NESTED:              支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。

    <tx:method/> 有关的设置

    属性是否需要?默认值描述
    name  

    与事务属性关联的方法名。通配符(*)可以用来指定一批关联到相同的事务属性的方法。如:'get*''handle*''on*Event'等等。

    propagation REQUIRED 事务传播行为
    isolation DEFAULT 事务隔离级别
    timeout -1 事务超时的时间(以秒为单位)
    read-only false 事务是否只读?
    rollback-for  

    将被触发进行回滚的 Exception(s);以逗号分开。 如:'com.foo.MyBusinessException,ServletException'

    no-rollback-for  

     被触发进行回滚的 Exception(s);以逗号分开。 如:'com.foo.MyBusinessException,ServletException'

     

  • 相关阅读:
    *** Assertion failure in -[UICollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:viewCategory
    linker command failed with exit code 1 (use -v to see invocation)
    谈谈我对PhoneGap的看法——(摘自唐巧的技术博客)
    ssh key一键自动化生成公钥私钥,并自动分发上百服务器免密码交互
    2018年Linux运维人员必会开源运维工具体系总结
    CentOS 6下PXE+Kickstart无人值守安装操作系统
    IOS优秀博客
    Nginx简单实现网站的负载均衡
    堆排序 Heap Sort
    h5移动端设计页面
  • 原文地址:https://www.cnblogs.com/jtlgb/p/10435450.html
Copyright © 2011-2022 走看看