1.什么是事务?
- 事务是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作;
- 事务作为一个整体一起向系统提交,要么都执行、要么都不执行;
- 事务是一组不可再分割的操作集合。
2.事务ACID原则:
原子性: 事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做。要么都成功,要么都失败。
一致性: 事务执行完的结果必须是使数据库从一个一致性状态变到另一个一致性状态。与原子性密切相关。好比银行取钱,用户取了钱后,数据库的数据要相应的减少。保证他们的一致性。
隔离性: 事务的隔离性要求事务之间是彼此独立的,隔离的。一个事务的执行不可以被其他事务干扰。具体到操作是指一个事务的操作必须在一个事务commit提交之后才可以进行操作。
持久性: 也称永久性,一个事务一旦提交,它对数据库中的数据的改变就是永久性的。 接下来的其它操作或故障不应该对其执行结果有任何影响。
3.事务的传播方式propagation
1、REQUIRED:默认事务类型,如果没有,就新建一个事务;如果有,就加入当前事务。适合绝大多数情况。
2、REQUIRES_NEW:如果没有,就新建一个事务;如果有,就将当前事务挂起。
3、NESTED:如果没有,就新建一个事务;如果有,就在当前事务中嵌套其他事务。
4、SUPPORTS:如果没有,就以非事务方式执行;如果有,就使用当前事务。
5、NOT_SUPPORTED:如果没有,就以非事务方式执行;如果有,就将当前事务挂起。即无论如何不支持事务。
6、NEVER:如果没有,就以非事务方式执行;如果有,就抛出异常。
7、MANDATORY:如果没有,就抛出异常;如果有,就使用当前事务。
一般来讲REQUIRED常用于增删改,SUPPORTS用于查询,REQUIRES_NEW用于日志。
3.spring声明式事务
1.创建DataSourceTransactionManager 对象:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource" />
</bean>
2.结合Aop织入事务
1.导入tx注解支持(参考aop-config)
2.配置事务通知
<!-- propagation:事务的传播方式-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 给方法配置事务-->
<tx:method name="selectUser" read-only="true"/>
<tx:method name="selectAllUser" read-only="true"/>
<tx:method name="updateUser" propagation="REQUIRED"/>
<tx:method name="delUser" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<!-- 切入点:指定事务通知的切入点是什么-->
<aop:pointcut id="txPointCut" expression="execution(* com.kxy.mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
配置事务通知是建立在Aop切面的通知基础上的,也就是说,事务通知有了切入点,便可以等待事务通知执行完毕。
总结:
spring管理事务有两种方式,声明式事务和编程式事务。声明式事务就是在不改变原有业务的情况下实现事务的织入。而编程式事务,需要在具体业务中进行事务的管理。
为什么需要事务?如果不配置事务,可能会导致数据不一致。同样的也不满足原子性。降低了安全性。为了不再代码中手动的配置事务,我们用spring的声明式事务。