事务
访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。
事务的ACID
原子性(Atomicity)
事务是不可分割的最小工作单元,内部操作要么都做,要么都不做。
一致性(Consistency)
在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
隔离性(Isolation)
隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。
持久性(Durability)
事务一旦执行成功,它对数据库的影响是持久的,并不会被回滚。
并发执行问题
丢失更新
两个事务同时更新一行数据,最后一个事务的更新会覆盖掉上一个事务的更新,从而导致上一个事务更新的数据丢失,这是因为没有加锁造成的。
脏读
一个事务看到了另外一个事务还没提交的更新数据
不可重复读
在同一个事务中,多次读取同一数据,却返回不同的数据结果。这是因为其他事务更改了这些数据。
幻读
A事务在执行过程中,读取到了B事务提交的插入数据;即在A事务开始的时候读取到一批数据,但在B事务插入新数据之后,A又读取就多了一条,就像产生幻觉一样。
隔离级别
default 使用后端数据库默认的隔离级别
read-uncommited 允许你读取还未提交的改变了的数据
read-commited 允许在并发事务已经提交后的读取
repeatable-read 对相同字段的多次读取是一致的,除非数据被事务改变。
serializable 完全服从ACID的隔离级别,确保不发生数据库并发问题。隔离级别最高,但是效率最慢。
Spring控制事务的方式
是以bean组件的方法为单位的,如果一个方法正常执行完毕,该方法内的全部数据库,按照一次事务提交,如果抛出异常,全不回滚(rollback)
事务的传播策略
如果两个Bean组件都由spring控制事务,且组件间的方法之间存在调用关系,Spring提供了一组配置方式供开发者选择,这些配置称为事务的传播策略
事务的隔离级别是数据库本身的事务功能,而事务的传播属性则是spring为我们提供的功能,数据库事务没有传播属性这一说法
required 业务方法需要在一个事务中运行,如果方法运行时,已经处在事务中,那么加入到该事务,否则为自己创建一个新的事务。
requiresnew 不管之前是否有事务,都创建一个新的事务。
never 不能包含任何事务。否则会抛出异常。
。。。。
事务的分类
本地事务
就是普通事务,能保证单台数据库上操作的ACID
分布式事务
涉及两个或者多个数据库的事务,即跨越多台同类或者异类数据库的事务,由每台数据库本地事务组成,分布式事务旨在保证这些本地所有操作的ACID,使事务可以跨越多台数据库。
编程式事务(不推荐)
通过编写代码,实现事务。配置bean,注入后在某个方法中的就是一个事务。
声明式事务(推荐)
通过注解或者XMl配置文件指定事务信息。
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
<property name="dataSource" ref="数据库连接的bean"/>
</bean>
<context:component-scan base-package="com.chinasofit.spring.sp"/>(包扫描)
<tx:annotation-driven transaction-manager="transactionManager">(注解驱动)
添加@Transactional注解
在此注解上配置事务的属性。(用在类上,表名该类所有方法都生效)