1、事务回顾 (1)、什么是事务:
事务是逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败。
(2)、事务特性(ACID)原子性 :强调事务的不可分割
一致性 :事务的执行的前后数据的完整性保持一致
隔离性 :一个事务执行的过程中,不应该受到其他事务的干扰
持久性 :事务一旦结束,数据就持久到数据库
(3)、事务并发安全性问题脏读 :一个事务读到了另一个事务的未提交的数据
不可重复读 :一个事务读到了另一个事务已经提交的 update 的数据导致多次查询结果不一致
幻读 :一个事务读到了另一个事务已经提交的 insert 的数据导致多次查询结果不一致
(4)、事务隔离级别未提交读 :脏读,不可重复读,幻读都有可能发生
已提交读 :避免脏读,但是不可重复读和幻读有可能发生
可重复读 :避免脏读和不可重复读,但是幻读有可能发生
串行化 :避免以上所有读问题
(5)、常见数据库默认事务隔离级别MySQL:可重复读
Oracle:读已提交
2、Spring 事务管理 (1)、基本事务操作打开事务
提交事务
回滚事务
(2)、事务操作对象Spring 事务管理中提供了 PlatformTransactionManager 接口操作事务,其中最为核心的对象是 TransactionManager 对象。
(3)、Spring 事务隔离级别读未提交
读已提交
可重复读
串行化
(4)、Spring 事务传播行为保证同一个事务中
PROPAGATION_REQUIRED :支持当前事务,如果不存在 就新建一个(默认)
PROPAGATION_SUPPORTS :支持当前事务,如果不存在,就不使用事务
PROPAGATION_MANDATORY :支持当前事务,如果不存在,抛出异常
保证不在同一个事务中
PROPAGATION_REQUIRES_NEW :如果有事务存在,挂起当前事务,创建一个新的事务
PROPAGATION_NOT_SUPPORTED :以非事务方式运行,如果有事务存在,挂起当前事务
PROPAGATION_NEVER :以非事务方式运行,如果有事务存在,抛出异常
PROPAGATION_NESTED :如果当前事务存在,则嵌套事务执行
3、Spring 事务管理方式 (1)、编码式将核心事务管理器配置到 Spring 容器
<!-- 事务核心管理器,封装了所有事务操作. 依赖于连接池 --><bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
<property name="dataSource" ref="dataSource" ></property>
</bean>
配置TransactionTemplate模板
<!-- 事务模板对象 --><bean name="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate" >
<property name="transactionManager" ref="transactionManager" ></property>
</bean>
将事务模板注入Service
<!-- 将 demoDao 和事务模板注入 Service--><bean name="demoService" class="com.spring.service.demoServiceImpl" >
<property name="dm" ref="demoDao" ></property>
<property name="tt" ref="transactionTemplate" ></property>
</bean>
在Service中调用模板
(2)、xml 配置方式
导入所需要的 jar 包和约束
配置事务通知
<!-- 配置事务通知 --><tx:advice id="txAdvice" transaction-manager="transactionManager" >
<tx:attributes>
<!-- 以方法为单位,指定方法应用什么事务属性
isolation:隔离级别
propagation:传播行为
read-only:是否只读
-->
<tx:method name="save*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
<tx:method name="persist*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
<tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
<tx:method name="modify*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
<tx:method name="delete*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
<tx:method name="remove*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
<tx:method name="get*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" />
<tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" />
<tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
</tx:attributes>
</tx:advice>