Spring框架的事务

一.什么是事务?

事务:是数据库操作的最小工作单元,是作为单个逻辑执行的一系列操作;这些操作作为一个整体一起向系统提交,要么都执行,要么都不执行;事务是一组不可在分割的操作集合。

事务是恢复和并发控制的基本单位。

事务具有四个特征:原子性、一致性、隔离性和持久性。这四个特征通常称为ACID。

二.事务的特性(ACID)

原子性(Atomicity): 一个事务(transaction)中的所有操作,或者全部完成,或者全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。即,事务不可分割、不可约简。

一致性(Consistency): 在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设约束、触发器、级联回滚等。

隔离性(Isolation): 数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括未提交读(Read uncommitted)、提交读(read committed)、可重复读(repeatable read)和串行化(Serializable)。
持久性(Durability):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

3.事务的隔离级别

数据库事务的隔离级别有4种,由低到高分别为Read uncommitted、Read committed、Repeatable read.Serializable。而且,在事务的并发操作中可能会出现脏读,不可重复读,幻读、事务丢失。

脏读:(读取了未提交的新事务,然后被回滚了)
事务A读取了事务B中尚未提交的数据。如果事务B回滚,则A读取使用了错误的数据.

不可重复读: (读取了提交的新事务,指更新操作)
不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。
幻读: (也是读取了提交的新事务,指增副操作)
在事务A多次读取构成中,事务B对数据进行了新增操作,导致事务A多次读取的数据不一致

第一类事物丢失: (称为回滚丢失)

对于第一类事物丢失,就是比如A和B同时在执行一个数据,然后B事物已经提交了,然后A事物回滚了,这样B事物的操作就因A事物回滚而丢失了
第二类事物丢失:(提交覆盖丢失)
对于第二类事物丢失,也称为覆盖丢失,就是A和8一起执行一个数据,两个同时取到一个数据,然后B事物首先提交,但是A事物加下来又提交,这样就覆盖了B事物

Read uncommitted
读未提交,顾名思义,就是一个事务可以读取另一个未提交美务的数据。会产生脏读。
Read committed
读提交,顾名思义,就是一个事务要等另一个事务提交后才能读取数据。 会产生不可重复读。
Repeatable read
重复读,就是在开始读取数据(事务开启)时,不再允许修改操作。 可能会产生幻读。
Serializable
Serlalizable 是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。

大多数数据库默认的事务隔离级别是Read committed,比如sql Server,Oracle.
Mysal的默认隔离级别是Repeatable read

4.事务传播行为(为了解决业务层方法之间互相调用的事务问题):

当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。在TransactionDefinition定义中包括了如下几个表示传播行为的常量:

1、PROPAGATION_REQUIRED:默认事务类型;如果没有,就新建一个事务;如果有,就加入当前事务。适合大多数情况。

2、PROPAGATION_REQUIRES_NEW: 如果没有,就新建一个事务;如果有,就将当前事务挂起.

3、PROPAGATION_NESTED: 如果没有,就新建一个事务;如果有,就在当前事务中嵌套其他事务.

4、PROPAGATION SUPPORTS: 如果没有,就以非事务方式执行:如果有,就使用当前事务

5、PROPAGATION NOT SUPPORTED:如果没有,就以非事务方式执行,如果有,就将当前事务挂起。即无论如何不支持事务
6、PROPAGATION_NEVER:如果没有,就以非事务方式执行,如果有,就抛出异常

7、PROPAGATION MANDATORY: 如果没有,就抛出异常,如果有,就使用当前事务。

总结:

[1]死活不要事务的

PROPAGATION NEVER:没有就非事务执行,有就抛出异常

PROPAGATION_NOT_SUPPORTED:没有就非事务执行,有就直接挂起,然后非事务执行

[2]可有可无的

PROPAGATION SUPPORTS: 有就用,没有就算了

[3]必须有事务的

PROPAGATION_REQUIRES_NEW: 有没有都新建事务,如果原来有,就将原来的挂起PROPAGATION_NESTED:如果没有,就新建一个事务,如果有,就在当前事务中嵌套其他事务PROPAGATION REQUIRED:如果没有,就新建一个事务;如果有,就加入当前事务PROPAGATION MANDATORY:如果没有,就抛出异常,如果有,就使用当前事务。

这里需要指出的是,前面的六种事务传播行为是 Spring 从 EJB 中引入的,他们共享相同的概念。而 PROPAGATION_NESTED 是 Spring 所特有的。以 PROPAGATION_NESTED 启动的事务内嵌于外部事务中(如果存在外部事务的话),此时,内嵌事务并不是一个独立的事务,它依赖于外部事务的存在,只有通过外部的事务提交,才能引起内部事务的提交,嵌套的子事务不能单独提交。如果熟悉 JDBC 中的保存点(SavePoint)的概念,那嵌套事务就很容易理解了,其实嵌套的子事务就是保存点的一个应用,一个事务中可以包括多个保存点,每一个嵌套子事务。另外,外部事务的回滚也会导致嵌套子事务的回滚。
 

猜你喜欢

转载自blog.csdn.net/WJY898989/article/details/130098015