对事务的理解:事务是指修改数据库数据时,需要满足所有的操作要满足一致性,要么全都操作,要么全都不操作。例如,当我买一个商品时,大致的步骤如下:

1.数据库中商品的数量减一

2.我的账户余额减去商品的价格
当执行到第二步时,若发现我的余额不够支付该商品,本次购买便失败,系统应该恢复原来的商品数量(即需要回滚),这便是一个典型的事务,库存减一和账户消费必须一致,要么一起执行成功,要么都不执行。

事务的配置:

xml配置


<!--启用事务注解-->
<tx:annotation-driven transaction-manager="transactionManager">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="url" value="jdbc:mysql://localhost:3306/test"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>  
    </bean>
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dateSource" ref="dataSource"/>
    </bean>
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
         <tx:attributes>
               <tx:method name="add*" propagation="REQUIRED"/>
            <tx:method name="insert*" propagation="REQUIRED"/>
            <tx:method name="save*" propagation="REQUIRED"/>
            <tx:method name="delete*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="select*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="query*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
         </tx:attributes>     
    </tx:advice>
    <aop:config>
        <aop:pointcut expression="execution(* com.feng.part2.*(..))" id="txPointCut" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
    </aop:config>

spring支持的事务传播行为(xml配置中method的propagation属性便是):

1.REQURED:如果有事务在运行,当前的方法就在这个事务内运行,否则就启动一个新的事务,并在自己的内部运行、

2.REQURES_NEW:当前的方法必须启动新事物,并在他自己的事务内部运行,如果有事务在运行,应该将它挂起

3.SUPPORTS:如果有事务在运行,当前的方法就在这个事务内运行,否则它可以不运行在事务中

4.NOT_SUPPORTE:当前的方法不应该运行在事务中,如果有运行的事务,应将它挂起

5.MANDATORY:当前的方法必须运行在事务内部,如果没有正在运行的事务,就抛出异常

6.NEVER:当前的方法不应该运行在事务中,如果有运行的事务,就抛出异常

7.NESTED:如果有事务运行,当前的方法就应该在这个事务的嵌套事务内部运行,否则就启动一个新的事务,并将他在自己的的事务内运行


readOnly:该属性表示指定的事务为只读,表示这个事务只读数据但是不更新数据,这样可以帮助数据库引擎优化事务。若一个方法只读取数据,建议设置只读属性。我的配置中,将所有的以find,select,query,get开头的查询方法都设置为了只读,这将大大提高查询效率。



事务回滚:spring声明式事务默认情况下对所有的运行时异常进行回滚,也可以配置noRollbackFor="异常名",遇到此异常将不回滚。通常情况下,不会配置这个属性。