关于spring的事务管理的具体对象
Spring的声明式事务管理配置如下
<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="save*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="create*" 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="get*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 切面 -->
<aop:config>
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.taotao.order.service.*.*(..))" />
</aop:config>
需要配置AOP的切面,对切面的类进行扫描,利用cglib或者jdk的动态代理技术,采用环绕增强方式,在方法的开始前开启事务,在方法的return语句执行前(结束前)处理事务。所以事务管理的基本单位是方法而不是操作
举例:
一个方法需要操作数据库的三个表, 在其中一个表的操作出现问题后,观察其执行结果
order.setOrderId(orderId.toString());
order.setStatus(1);
order.setUpdateTime(new Date());
order.setCreateTime(new Date());
order.setBuyerRate(0);
orderMapper.insert(order);
for (TbOrderItem tbOrderItem : itemList) {
Random random = new Random();
Integer end4 = random.nextInt(9999);//实际生成0-9999之间的随机数
String id=orderId.toString()+end4.toString();
System.out.println(orderId+"--->"+end4);
tbOrderItem.setId(id);
tbOrderItem.setOrderId(orderId.toString());
orderItemMapper.insert(tbOrderItem);
}
orderShipping.setOrderId(orderId.toString());
orderShipping.setCreated(new Date());
orderShipping.setUpdated(new Date());
int a =1/0; <--此时出现错误
orderShippingMapper.insert(orderShipping);
return TaotaoResult.ok(orderId);
在方法执行结束后,观察数据库的变化
可以看到在对orderShipping表的操作出现问题,但是对于同一个方法之前的操作表tborderitem和表tborder也没有数据,说明三个表的操作都回滚了。所以事务管理的基本单位是方法而不是操作
方法内的代码出现异常,会回滚整个方法内对数据库的所有操作