spring 事物

spring 事物

事物有四大特征:原子性,一致性,隔离性,持久性

事务定义了四种隔离级别:Read uncommitted、Read committed、Repeatable read和Serializable。
关于这四种隔离级别,其主要区别在于三个点:脏读、不可重复读和幻读。这三个点的主要含义如下:

  • 脏读:脏读表示一个事务能够读取另一个事务中还未提交的数据。比如,某个事务尝试插入记录A,此时该事务还未提交,然后另一个事务尝试读取记录A,这时其是会成功读取到记录A的;

  • 不可重复读:不可重复读表示当前事务对同一记录的两次重复读取结果不一致。比如一个事务首先读取一条记录A,读完之后另一个事务将该记录修改并且成功提交了,然后当前事务再次读取记录A,此时该事务会发现两次读取的结果不一致;

  • 幻读:幻读指的是一个事务在进行一次查询之后发现某个记录不存在,然后会根据这个结果进行下一步操作,此时如果另一个事务成功插入了该记录,那么对于第一个事务而言,其进行下一步操作(比如插入该记录)的时候很可能会报错。从事务使用的角度来看,在检查一条记录不存在之后,其进行插入应该完全没问题的,但是这里却抛出主键冲突的异常。

    隔离级别

  • read uncommited:是最低的事务隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。

  • read commited:保证一个事物提交后才能被另外一个事务读取。另外一个事务不能读取该事物未提交的数据。

  • repeatable read:这种事务隔离级别可以防止脏读,不可重复读。但是可能会出现幻象读。它除了保证一个事务不能被另外一个事务读取未提交的数据之外还避免了以下情况产生(不可重复读)。

    一个事物第一次查询,中间插入,第二次查询,两次查询结果一样,都读不到两次查询中间插入的数据(修改数据原理一样)
  • serializable:这是花费最高代价但最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读之外,还避免了幻象读(避免三种)。

    spring 默认的是default 也就是默认数据库的隔离级别 ;
    mysql 的默认隔离级别是 repeatable read;
    orcle 的默认级别是 read commited

事物传播类型:

支持当前事物:
    propagation_required 必须的 如果当前没有事物,就新创建一个,如果存在别的事物当中,就加入到当前事物,使用父事物,常用
            a调用b,a有事物,b没有事物,在执行时,默认把b加到a的事物中去
    propagation_supports. 支持当前事物,如果当前没有事物,就以非事物方式运行
    porpagation_mandatory 使用当前事物,如果没有,抛异常
不支持当前事物:
    propagation_requireds_new: 新建事物,如果当前存在事物,挂起,使用新事物
    propagation_not_supports: 以非事物方式运行,如果当前存在,挂起
    propagation_never(强制非事物):以非事物方式运行,如果存在事物,抛异常
嵌套事物:
    propagation_nested: 如果当前存在事物,嵌套在事物内执行,没有,使用propagation_required执行