事务
一组具有明确边界的,并且是有一定顺序的执行过程。
是企业开发过程中必不可少的一门技术。
通常用来确保一组执行过程的完整性与一致性。
例如:张三给李四转钱,这就是一个完整的过程,任何一部出问题,事务都是不完整的。
事务的四大特征:
原子性(Atomicity):事务是一个完整的过程,不可以再次划分。具有原子的特征。一致性(Consistency):一旦事务进行,无论有多少个事务,处理事务的过程中,数据总是满足质量守恒定律。入多少---出多少。
隔离性(Isolation):事务与事务执行过程中,不同的事务之间是相互隔离的,互不干涉。
持久性(Durability):事务一旦确定下来,那么结果就必须要确实下来,不应该再次被同一事务进行破坏。如果要变动,也应该另起一个新的事务。
事务如果按照类型来进行分类:
逻辑事务:是为了保证业务逻辑的完整性与准确性。
物理事务:是为了保证业务数据的准确性。
通常来说:一个逻辑事务包含多个物理事务 。
在spring框架内,处理事务,通常有2种方式:
编程试事务:将事务管理的代码嵌入到业务逻辑的方法上,通过这种方式来控制事务的提交或者回滚。 这种方式简单粗暴,但是有个缺点:在编程式事务中,必须在每个业务操作的方法上都包含额外的事务管理代码。
声明式事务:将事务管理代码从业务中分离出来,交给springAOPen切面来进行管理。我们只需要在spring配置文件中声明如何去管理事务就可以了,在企业应用开发中,声明式事务较为常见。
事务的隔离级别:
1.可串行化(Serializable)---这是事务处理的最高隔离级别,相当于线程同步后的结构,它不能保证得到的是什么结果,但至少可以保证得到的是准确的。
其他的隔离级别虽然处理事务的效率有所提升,但是都会在一定程度上导致数据的不准确。
2.可重复读(Repeatable Read)---使用较为广泛,它的隔离级别仅次于可串行化,但是会产生一个问题:它会导致幻读,给操作者造成不应该有的幻觉。
------所谓幻读,是指当前事务不是独立执行的时候发生的情况,例如:
------有两个事务操作同一张表,A的事务修改了表中大部分数据,并且做了提交,但是尚未查询。B的事务刚好修改到A操作数据中的一部分数据,然后A再查询,这个时候就会给A造成一种没修改完毕的幻觉。
3.读已提交(Read committed)---它的隔离级别仅次于可重复度,但是它同样也有一个问题:它会导致不可重复读。
所谓的不可重复读是在数据库访问过程中,一个事务范围内两次或多次的查询结果不一致。在同一个事务中,多次读取同一数据,得到的结果却是不一样的。它是由于在读的间隙过程中,有另外一个事务修改了同样的数据,从而导致前一个事务多次得到的结果不一致。
对于数据库而言,不可重复读要比幻读来得更加容易一些,因此“可重复读”比“读已提交”有更好的正确性。所以项目中更多的使用可重复读。
4.读未提交(Read uncommitted)---隔离级别最低,项目中几乎没有人使用,其原因是:它会导致脏读,事务在处理的过程中,可以读取到其他事务尚未提交的数据,然后对尚未提交的数据进行业务处理。
项目中具体应该采用哪种隔离级别,要根据系统所在业务环境具体分析
事务的传播,当多个具有事务能力的Service实现类的方法互调的时候,所形成的复杂事务边界控制的问题。
Spring框架中常见的事务传播控制方式有以下7种:
(调用者---被调用者 支持当前事务,是指调用者如果拥有事务,被调用者也要遵循该事务)
1.REQUIRED:支持当前事务,如果没有事务,就新建一个事务------(CUD)★★★
2.REQUIRES_NEW:无论调用者有没有事务,都新建一个新的事务,如果有事务,则将事务挂起,按照新的事务来执行。
3.SUPPORTS:如果有事务,则支持当前事务,如果没有事务,则以非事务方式执行★★★
4.MANDATORY:如果有事务,在支持当前事务,如果没有事务,则抛出无事务异常
5.NOT-SUPPORTED:以非事务方式执行,如果有事务,就事务挂起
6.NEVER:绝对不能在事务环境下运行,如果有事务,就将事务挂起,该传播对应的方法只有在没有关联到事务的情况下才会执行。
7.如果调用者与被调用者同时拥有事务,则将被调用者的事务嵌套到调用者的事务中,如果没有事务,则按照第一种方式来处理。