Spring事务管理
一、事务
1、事务概念
事务是由步数据库操作序列组成的逻辑执行单元,这系列操作要么全部执行,要么全部放弃执行 ,事务是一组不可再分割的操作集合。
2.事务特性(原子性,一致性,隔离性,持久性)
2.1原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。
2.2一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。
2.3隔离性(Isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
2.4持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。
3、事务的传播特性
事务传播行为就是多个事务方法调用时,如何定义方法间事务的传播。Spring定义了7中传播行为:
3.1 propagation_requierd:如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,这是Spring默认的选择。
3.2 propagation_supports:支持当前事务,如果没有当前事务,就以非事务方法执行。
3.3 propagation_mandatory:使用当前事务,如果没有当前事务,就抛出异常。
3.4 propagation_required_new:新建事务,如果当前存在事务,把当前事务挂起。
3.5 propagation_not_supported:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
3.6 propagation_never:以非事务方式执行操作,如果当前事务存在则抛出异常。
3.7 propagation_nested:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与propagation_required类似的操作。
4.事务隔离级别
4.1读未提交(Read Uncommitted)
只处理更新丢失。如果一个事务已经开始写数据,则不允许其他事务同时进行写操作,但允许其他事务读此行数据。可通过“排他写锁”实现。(加写锁,直到事务结束后才释放)
4.2读提交(Read Committed)
处理更新丢失、脏读。读取数据的事务允许其他事务继续访问改行数据,但是未提交的写事务将会禁止其他事务访问改行。可通过“瞬间共享读锁”和**“排他写锁**”实现。(一般情况下,使用此级别即可)(加写锁,直到事务结束后才释放;加读锁,读完之后立刻释放)
4.3可重复读取(Repeatable Read)
处理更新丢失、脏读和不可重复读取。读取数据的事务将会禁止写事务,但允许读事务,写事务则禁止任何其他事务。可通过**“共享读锁”和“排他写锁”**实现。(加写锁,直到事务结束后才释放;加读锁,直到事务结束后才释放)
4.4序列化(Serializable)
提供严格的事务隔离。要求失去序列化执行,事务只能一个接一个地执行,不能并发执行。仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。
4.5脏读、不可重复读、幻象读(不事务隔离会导致的结果):
a.脏读:指当一个事务正字访问数据,并且对数据进行了修改,而这种数据还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据还没有提交那么另外一个事务读取到的这个数据我们称之为脏数据。
b.不可重复读:指在一个事务内,多次读同一数据。在这个事务还没有执行结束,另外一个事务也访问该同一数据,那么在第一个事务中的两次读取数据之间,由于第二个事务的修改第一个事务两次读到的数据可能是不一样的,这样就发生了在一个事物内两次连续读到的数据是不一样的,这种情况被称为是不可重复读。
c.幻象读:一个事务先后读取一个范围的记录,但两次读取的纪录数不同,我们称之为幻象读(两次执行同一条 select 语句会出现不同的结果,第二次读会增加一数据行,并没有说这两次执行是在同一个事务中)
5.事务配置
5.1 事务管理方式
a.编程式事务是指应用通过使用spring提供的各个事务相关的类,通过编写代码来完成事务的设置,业务代码和事务规则高度耦合,这种的使用门槛较高,使用难度稍大一些,而且不方便,大多数时候我们并不会用到。
b.声明式事务则指通过配置的形式来引入spring的事务管理,具体的配置方式又可以分为通过XML文件配置和通过注解配置。由于配置方式上手容易,需要配置的内容也不多,尤其是基于注解的配置,已经成了目前引入事务的首选。
5.2事务实现方式
a.编程式事务管理:我们需要在代码中调用beginTransaction()、commit()、rollback()等事务管理相关的方法
b.声明式事务管理 :
(1)基于Spring的xml的声明式事务管理
编写Spring配置文件:
(2)基于注解的声明式事务管理
编写配置类:
事务开启对应的业务层实现类加上注解:
二.总结
1.编程式事务允许用户在代码中精确定义事务的边界,编程式事务侵入到了业务代码里面,但是提供了更加详细的事务管理;
2.声明式事务由于基于AOP,所以既能起到事务管理的作用,又可以不影响业务代码的具体实现。而声明式事务(基于AOP)有助于用户将操作与事务规则进行解耦(更优的选择)。