Spring支持编程式事务管理和声明式的事务管理。spring
编程式事务管理数据库
将事务管理代码嵌到业务方法中来控制事务的提交和回滚express
缺点:必须在每一个事务操做业务逻辑中包含额外的事务管理代码编程
声明式事务管理
通常状况下比编程式事务好用。app
将事务管理代码从业务方法中分离出来,以声明的方式来实现事务管理。框架
将事务管理做为横切关注点,经过aop方法模块化。Spring中经过Spring AOP框架支持声明式事务管理。
ide
下面是声明式事务的两种实现方法模块化
根据方法名自动为对应的方法添加事务优化
<!-- 1. 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 2. 配置事务属性 --> <!--<tx:advice>元素声明事务通知--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 事务管理的方法名 --> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="append*" propagation="REQUIRED" /> <tx:method name="insert*" propagation="REQUIRED" /> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="modify*" propagation="REQUIRED" /> <tx:method name="edit*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="remove*" propagation="REQUIRED" /> <tx:method name="repair" propagation="REQUIRED" /> <tx:method name="delAndRepair" propagation="REQUIRED" /> <tx:method name="get*" propagation="REQUIRED" /> <tx:method name="datagrid*" propagation="REQUIRED" /> <tx:method name="query*" propagation="SUPPORTS" read-only="true" /> <tx:method name="select*" propagation="SUPPORTS" read-only="true" /> <tx:method name="find*" propagation="SUPPORTS" read-only="true" /> <tx:method name="load*" propagation="SUPPORTS" read-only="true" /> <tx:method name="search*" propagation="SUPPORTS" read-only="true" /> <tx:method name="count*" propagation="SUPPORTS" read-only="true" /> <tx:method name="truncate*" propagation="SUPPORTS" read-only="true" /> <tx:method name="menu*" propagation="SUPPORTS" read-only="true" /> <tx:method name="exist*" propagation="SUPPORTS" read-only="true" /> <tx:method name="exist*" propagation="SUPPORTS" read-only="true" /> </tx:attributes> </tx:advice> <!-- 3. 配置事务切入点, 以及把事务切入点和事务属性关联起来 --> <aop:config> <aop:pointcut expression="execution(* com.atguigu.spring.tx.xml.service.*.*(..))" id="txPointCut"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/> </aop:config>
Spring中注解的方式@Transactional标注事务方法。为了将方法定义为支持事务处理,能够在方法上添加@Transactional注解。根据Spring AOP基于代理机制,只能标注公有方法。若是在类上标注@Transactional注解,那么这个类中全部公有方法都会被定义为支持事务。
ui
<!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 启用事务注解 --> <tx:annotation-driven transaction-manager="transactionManager"/>
在方法上添加
//添加事务注解 //1.使用 propagation 指定事务的传播行为, 即当前的事务方法被另一个事务方法调用时 //如何使用事务, 默认取值为 REQUIRED, 即便用调用方法的事务 //REQUIRES_NEW: 事务本身的事务, 调用的事务方法的事务被挂起. //2.使用 isolation 指定事务的隔离级别, 最经常使用的取值为 READ_COMMITTED //3.默认状况下 Spring 的声明式事务对全部的运行时异常进行回滚. 也能够经过对应的 //属性进行设置. 一般状况下去默认值便可. //4.使用 readOnly 指定事务是否为只读. 表示这个事务只读取数据但不更新数据, //这样能够帮助数据库引擎优化事务. 若真的事一个只读取数据库值的方法, 应设置 readOnly=true //5.使用 timeout 指定强制回滚以前事务能够占用的时间. @Transactional(propagation=Propagation.REQUIRES_NEW, isolation=Isolation.READ_COMMITTED, noRollbackFor={UserAccountException.class}, rollbackFor = IOException.class, readOnly=false, timeout=3) @Override public void purchase(String username, String isbn) {}