mysql事物详解

前言:事物是什么?作为一个java程序员,也许我们仅仅只是停留在会使用的程度上,会通过在类上或者方法上使用@Transactional注解的方式来使用事物,但是背后的原理,为什么使用这个注解就能使事物生效可能并不是很清楚。下面本文详细一一介绍事物是什么,事物的特性,怎么使用等等。

1. 事物是什么

    所谓事物,在我的理解中就是一系列操作的一个集合,一旦其中一个操作失败,那么整个操作集合必须全部失败,回滚到事物之前的状态。事物的出现是为了确保数据的完整性和一致性。

2. 事物的特性

     事物具有四大特性:

          2.1. 原子性 :原子性是指事务是一个不可分割的工作单位,是一个整体,事务中的操作要么全部成功,要么全部失败。比如在同一个事务中的增删改的sql,要么全部执行成功,要么全部执行失败,全部失败的同时,数据必须回滚到事物操作的状态之前。

          2.2 一致性: 一致性指的是 事务在完成时,必须是所有的数据都保持一致状态(所有数据必须符合业务规则,否则事务必须中止),举个例子: 例如A和B的账户总和有1W块钱,不管A和B之间怎么进行转账,那么A和B的账户总额还是1W块钱,除非A或者B有取钱或存钱的动作,也就是说事物使数据库中的数据从一个一致性的状态到达另外一个一致性状态。

          2.3 隔离性:隔离性指的是:多个事物之间互不影响,并发访问数据库时,每个访问都会开启一个事物,多个事物之间具有隔离性,多个事物的操作的结果互不影响。

          2.4 持久性:持久性其实很好理解;就是事物一旦提交,那么事物操作对数据库中数据的影响必须是持久性的,即影响的数据必须是持久性的存储起来。

3. 事物的五种隔离级别 

    事物的四大特性中,最复杂,最难以理解的是事物的隔离性,多个线程并发访问数据库时,数据库必须提供相应的隔离性以确保操作之间不互相影响。

     如果数据库事物没有提供相应的隔离性,那么在并发操作数据库时,可能会出现下面的问题:

     1.  脏读 

          一个事务读到另一个事务未提交的更新数据,就是有A,B两个事物,B事物做了更新的操作,此时B事物还没有提交,但是在A事物中,能够读到B事物中提交的结果。

     2. 不可重复读

          不可能重复读是在同一个事物内,多次查询表中的同一行数据,发现多次查询的结果不一致。

不可重复读和脏读的区别在于,不可重复读读取的是同一个事物中已提交的数据,脏读读取的是不同事物中未提交的数据。

     3. 幻读

          幻读指的是:读取同一张表中的数据,发现多次读取的结果集不一致(也就是表中的数据总行数不一致),也就说读取到了另外一个事物插入的数据。

不可重复读和幻读的区别在于:不可重复读读取的是同一张表同一行的数据,而幻读读取的是同一张表中的数据。

mysql中的事物定义了四种隔离级别:
3.1 TRANSACTION_READ_UNCOMMITTED(读未提交)

       读未提交是 也就是上面说的脏读,是事物隔离级别中的最低级别,下面的三种情况都不能保证,也就说会产生脏读,不可重复读和幻读

3.2 TRANSACTION_READ_COMMITTED (读已提交)

       读已提交可以避免脏读的发生。也就是说一个事物提交了,那么提交的数据才能被另外一个事物读取,没有提交,是不能被另外一个事物读取的。

3.3 TRANSACTION_REPEATABLE_READ (可重复读)

       可重复读可以避免脏读和不可重复读的发生。但是可能出现幻读的情况发生。

3.4 TRANSACTION_SERIALIZABLE (串行化)

       串行化可以避免脏读和不可重复读和幻读的发生,这种是代价最为昂贵的但是最可靠的事物。

mysql中事物的默认隔离级别是TRANSACTION_REPEATABLE_READ (可重复读)

我们可以在sql命令行中使用select @@tx_isolation来查看当前数据库的事物隔离级别。

使用 set transaction isolation level 隔离级别名    来设置数据库的事物隔离级别。

其中mysql事物中能保证的功能越多,并发性能越差,其中TRANSACTION_SERIALIZABLE的并发性能是最差的。

    原文作者:EllisTian
    原文地址: https://blog.csdn.net/T2080305/article/details/82658220
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞