使用SpringBoot项目实现一个本地事务管理功能

  介绍

使用SpringBoot项目实现一个本地事务管理功能?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

1。SpringBoot事务

一直在用SpringBoot中的@ transactional来做事务管理,但是很少没想过SpringBoot是如何实现事务管理的,今天从源码入手,看看@ transactional是如何实现事务的,最后我们结合源码的理解,自己动手写一个类似的注解来实现事务管理,帮助我们加深理解。

1.1。事务的隔离级别

事务为什么需要隔离级别呢?这是因为在并发事务情况下,如果没有隔离级别会导致如下问题:

<李>

脏读(脏读):当一个事务对数据进行修改,但是这种修改还没有提交到数据库中,B事务同时在访问这个数据,由于没有隔离,B获取的数据有可能被一个事务回滚,这就导致了数据不一致的问题。

<李>

丢失修改(修改):当一个事务访问数据100年,并且修改为100 - 1=99,同时B事务读取数据也是100年修改数据100 - 1=99,最终两个事务的修改结果为99年,但是实际是98。事务一个修改的数据被丢失了。

<李>

不可重复读(不可重复读):指一个事务在读取数据X=100的时候,B事务把数据X=100修改为X=200,这个时候一个事务第二次读取数据X的时候,发现X=200了,导致了在整个一个事务期间,两次读取数据X不一致了,这就是不可重复读。

<李>

幻读(幻像读):幻读和不可重复读类似。幻读表现在,当一个事务读取表数据时候,只有3条数据,这个时候B事务插入了2条数据,当一个事务再次读取的时候,发现有5条记录了,平白无故多了2条记录,就像幻觉一样。

<强>不可重复读VS幻读

不可重复读的重点是修改:同样的条件,你读取过的数据,再次读取出来发现值不一样了,重点在更新操作。
幻读的重点在于新增或者删除:同样的条件,第1次和第2次读出来的记录数不一样,重点在增删操作。

所以,为了避免上述的问题,事务中就有了隔离级别的概念,在春天中定义了五种表示隔离级别的常量TransactionDefinition:

<李>

ISOLATION_DEFAULT:数据库默认的隔离级别,MySQL默认采用的REPEATABLE_READ隔离级别。

<李>

ISOLATION_READ_UNCOMMITTED:最低的隔离级别,允许读取未提交的数据变更,可能会导致脏读,幻读或不可重复读。

<李>

ISOLATION_READ_COMMITTED:允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。

<李>

ISOLATION_REPEATABLE_READ:对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生.MySQL中通过MVCC解决了该隔离级别下出现幻读的可能。

<李>

ISOLATION_SERIALIZABLE:串行化隔离级别,该级别可以防止脏读,不可重复读以及幻读,但是串行化会影响性能。

1.2。春天中事务的传播机制

为什么春天中要搞一套事务的传播机制呢?这是春天给我们提供的事务增强工具,主要是解决方法之间调用,事务如何处理的问题。比如有方法,方法B和方法C,在一个中调用了方法B和方法C .伪代码如下:

MethodA (), {   ,MethodB ();   ,MethodC ();   }

假设三个方法中都开启了自己的事务,那么他们之间是什么关系呢? MethodA的回滚会影响MethodB和MethodC吗?春天中的事务传播机制就是解决这个问题的。
春天中定义了七种事务传播行为:

<李>

PROPAGATION_REQUIRED:如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。

<李>

PROPAGATION_SUPPORTS:如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。但是对于事务同步的事务管理器,PROPAGATION_SUPPORTS与不使用事务有少许不同。

<李>

PROPAGATION_MANDATORY:如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。

<李>

PROPAGATION_REQUIRES_NEW:总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。

<李>

PROPAGATION_NOT_SUPPORTED:总是非事务地执行,并挂起任何存在的事务。

<李>

PROPAGATION_NEVER:总是非事务地执行,如果存在一个活动事务,则抛出异常。

<李>

PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按TransactionDefinition。PROPAGATION_REQUIRED属性执行。

使用SpringBoot项目实现一个本地事务管理功能