什么是事务
用户定义的一个数据库操作序列,这些操作要么都成功要么失败,是一个不可分割的工作单位。
事务特性
原子性:不可分割,事务由多个原子组成,这些原子要么全成功,要么全失败。
一致性:事务在执行前与执行后数据保持一致。
隔离性:事务与事务之间不可以互相影响。
持久性:事务一旦commit,代表数据真正修改了,不可以在改变。
事务管理
三个抽象接口
PlatformTransactionManager事务管理器 (控制事务核心API )
TransationDefinition 事务定义信息 (在xml配置文件,配置中如何对事务进行控制 )
TransactionStatus 事务状态信息 (在事务运行某个时刻,当前状态信息 )
事务的隔离级别
在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别。
数据库事务的隔离级别有4个,由低到高依次为Read uncommitted(未授权读取、读未提交)、Read committed(授权读取、读提交)、Repeatable read(可重复读取)、Serializable(序列化),这四个级别可以逐个解决脏读、不可重复读、幻读这几类问题。
问题的提出:
之所以提出事务隔离级别,是因为在一个事务执行过程中,可能会出现以下几种情况:
1)脏读:一个事务读取了另一个事务改写但是还未提交的数据,如果这些数据被回滚,则读到的数据是无效的。
2)不可重复读:一个事务执行相同的查询两次或两次以上,但每次查询结果都不同。
3)幻读(虚读):一个事务读取了几行记录后,另一个事务插入一些记录,幻读就发生了。在后来的查询中,第一个事务就会发现有些原来没有的数据。
四种隔离级别
Read uncommitted(读未提交):最低级别,任何情况都会发生。
Read Committed(读已提交):可避免脏读的发生。
Repeatable read(可重复读):可避免脏读、不可重复读的发生。
Serializable(串行化):避免脏读、不可重复读,幻读的发生。
事务的传播行为
1、required A开了一个事务,B也是requried,调用B时,如果有事务使用A的事务,如果没有事务,新建一个事务,A和B还是使用一个。
2、support,A开了一个事务 ,B是support,调用B时,如果有事务使用A的事务,如果没有事务,就不使用事务。
MANDATORY :A 调用B,B的传播行为MANDATORY, 支持A的事务,如果A没有事务,B抛出异常
3、REQUIRES_NEW:A调用B,B的传播行为 REQUIRES_NEW, 如果A存在事务,挂起A的事务,B创建新的事务运行 (两个事务) ------- 取款、打印凭条
4、NOT_SUPPORTED :A调用B,B的传播行为 NOT_SUPPORTED, 如果A存在事务,挂起A的事务,B不会开始事务运行
5、NEVER : A调用B,B的传播行为 NEVER, 如果A存在事务,B抛出异常
6、NESTED :嵌套事务,基于JDBC的SavePoint 在事务运行中记录保存点,当事务回滚时,回滚到指定保存点,而不需
要回滚到最开始 , 只对DataSourceTransactionManager 有效。 (嵌套事务,本质是一个事务 )
声明式事务管理
具体步骤
a. 在spring中配置注解
<!--开启注解扫描器-->
<context:component-scan base-package="bgs.com"></context:component-scan>
b.配置事务管理器
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="数据库配置信息"></property>
</bean>
c.编写增强
<tx:advice id="advice" transaction-manager="transactionManager">
//配置事务属性信息
<tx:attributes>
<tx:method name="对应方法名" propagation="传播行为"/>
</tx:advice>
d.定义切面
<aop:config>
//配置切点
<aop:pointcut expression="execution(* bgs.com.service.impl.*.*(..))" id="pointcut"/>
//配置切面
<aop:advisor advice-ref="advice" pointcut-ref="pointcut" />
</aop:config>
e.在Spring配置文件中添加事务注解驱动
<tx:annotation-driven/>