对事务的理解:事务是指修改数据库数据时,需要满足所有的操作要满足一致性,要么全都操作,要么全都不操作。例如,当我买一个商品时,大致的步骤如下:
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="异常名",遇到此异常将不回滚。通常情况下,不会配置这个属性。