mysql 事务

一、 事务特性

说到事务不得不提一下事务的特性:原子性、一致性、隔离性、持久性。下面是个人对这4个特性的理解:

原子性:

所谓的原子性就是事务不可再分,因为不可再分,所以在执行的时候也要么成功,要么失败,不存在一半成功一半失败的情况。

隔离性:

是指各个事物的执行都是独立、而且对同一数据的操作是互斥的。这主要是针对并发的,可能存在多个原子操作同时操作对应的数据,从而破坏数据的一致性,比如我们常说的读脏数据、重读、幻读的情况。

一致性:

想到当初学习时候,看的文章是A\B两人转钱,但总额不变的例子,这是一致性的一个例子,但是个人更认为这个一致性也是针对并发性的,设置隔离性也是为了保证一致性,所以一致性更应该体现在数据库内部数据和显示的一致性。

持久性:

就是通过原操作成功的事务,都会存库,会持久保存数据。

二、 mysql事务操作

先看一段代码,看看mysql事务的特性。首先个人创建了一个新的数据库和表:

mysql> select * from transaction;
Empty set (0.01 sec)

好,在不使用事务的情况下,我们插入2条数据:

mysql> select * from transaction;
Empty set (0.01 sec)

mysql> insert into transaction (name) values("HCC");
^[[5~Query OK, 1 row affected (0.46 sec)

mysql> insert into transaction (name) values("Marry");
Query OK, 1 row affected (0.21 sec)

mysql> select * from transaction;
+----+-------+
| id | name  |
+----+-------+
|  1 | HCC   |
|  2 | Marry |
+----+-------+
2 rows in set (0.00 sec)

不使用事务的时候,我们插入数据就直接成功了,接下来我们用事务试试:

mysql> insert into transaction (name) values("SMK");
Query OK, 1 row affected (0.00 sec)

mysql> insert into transaction (name) values("ZZD");
Query OK, 1 row affected (0.00 sec)

mysql> select * from transaction;
+----+-------+
| id | name  |
+----+-------+
|  1 | HCC   |
|  2 | Marry |
|  3 | SMK   |
|  4 | ZZD   |
+----+-------+
4 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.13 sec)

mysql> select * from transaction;
+----+-------+
| id | name  |
+----+-------+
|  1 | HCC   |
|  2 | Marry |
+----+-------+
2 rows in set (0.00 sec)

先讲述下上述的操作,首先我们开启了事务,然后插入2条数据,然后到数据库中查询数据的时候看到数据库多了2条数据,然后再事务没提交的情况下,执行rollback,再去查询发现我们插入的数据不见了。。

原因就是:我们开启事务后(begin),mysql将接下来的操作当成一个事务处理,也就是下面全部的操作是一个原子操作,再不提交的前提下,这个事务就没完成,执行rollback相当于实行失败,而回滚,所以你在查的时候发现数据库中并没用这两条数据。。。

有一个疑问,当开启事务后添加的数据真的添加到数据库中了吗,看代码

---------第一个终端----

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into transaction (name) values("SMK");
Query OK, 1 row affected (0.00 sec)

mysql> insert into transaction (name) values("ZZD");
Query OK, 1 row affected (0.00 sec)

mysql> select * from transaction;
+----+-------+
| id | name  |
+----+-------+
|  1 | HCC   |
|  2 | Marry |
|  5 | SMK   |
|  6 | ZZD   |
+----+-------+
4 rows in set (0.00 sec)

-------开启第二个终端链接--------
mysql> select * from transaction;
+----+-------+
| id | name  |
+----+-------+
|  1 | HCC   |
|  2 | Marry |
+----+-------+
2 rows in set (0.00 sec)

通过上述代码,我们发现在另一个链接中,我们事务插入的数据并没有得到,所以感觉并不像将数据插入到数据库了,但有趣的是id直接变成5,6了,具体查没插入数据库中,我们提交事务看看第二个终端的id就可以了。。。。或者在第二个终端插入数据看id。。。。

----------第二个终端插入数据------------

mysql> insert into transaction (name) values ("zwt")
    -> ;
Query OK, 1 row affected (0.17 sec)

mysql> select * from transaction;
+----+-------+
| id | name  |
+----+-------+
|  1 | HCC   |
|  2 | Marry |
|  7 | zwt   |
+----+-------+
3 rows in set (0.00 sec)


-------------第一个终端查看---------------------

mysql> select * from transaction;
+----+-------+
| id | name  |
+----+-------+
|  1 | HCC   |
|  2 | Marry |
|  5 | SMK   |
|  6 | ZZD   |
+----+-------+
4 rows in set (0.00 sec)

哈哈哈,会发现 第二个终端中没5,6, 第一个终端没有没有7,什么鬼??????

总结:

第二终端不显示id为5和6的条目原因:是这样的,事务在没提交的时候,对数据库进行了操作,但是没提交相当于这个原子性的事务还没执行完,而且数据库事务的隔离性采用的是repeatable,所以在第二个终端中,并没有显示,但是事务操作的已经“占位”了

第一终端不显示id 为7的条目,是因为事务没执行完,还处在事物的当中啊,哇哈哈哈。。。。是不是这样。。。0.0

提交事务,结果如下:

--------第一终端----------
mysql> commit;
Query OK, 0 rows affected (0.20 sec)

mysql> select * from transaction;
+----+-------+
| id | name  |
+----+-------+
|  1 | HCC   |
|  2 | Marry |
|  5 | SMK   |
|  6 | ZZD   |
|  7 | zwt   |
+----+-------+
5 rows in set (0.00 sec)

---------第二终端-----------

mysql> select * from transaction;
+----+-------+
| id | name  |
+----+-------+
|  1 | HCC   |
|  2 | Marry |
|  5 | SMK   |
|  6 | ZZD   |
|  7 | zwt   |
+----+-------+
5 rows in set (0.00 sec)

三 mysql中的事务操作

参考菜鸟:

  • BEGIN 或 START TRANSACTION:显式地开启一个事务;

  • COMMIT 或 COMMIT WORK:COMMIT会提交事务,并使已对数据库进行的所有修改成为永久性的;

  • ROLLBACK 或 ROLLBACK WORK,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;

  • SAVEPOINT identifier;SAVEPOINT允许在事务中创建一个保存点,一个事务中可以有多个SAVEPOINT;

  • RELEASE SAVEPOINT identifier;删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;

  • ROLLBACK TO identifier;把事务回滚到标记点;

  • SET TRANSACTION;用来设置事务的隔离级别。InnoDB存储引擎提供事务的隔离级别有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ和SERIALIZABLE。

前边其实使用的就是begin、commit和rollback,下面试试 savepoint、 release savepoint、 rollback to identifier以及  SET TRANSACTION。   
 

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into transaction (name) values ("MR");
Query OK, 1 row affected (0.00 sec)

mysql> insert into transaction (name) values ("ZL");
Query OK, 1 row affected (0.00 sec)

#############加入MR、ZL后,加入一个保存点,然后接着插入ZH,并查询数据############

mysql> savepoint pont1;
Query OK, 0 rows affected (0.01 sec)

mysql> insert into transaction (name) values ("ZH");
Query OK, 1 row affected (0.01 sec)

mysql> select * from transaction;
+----+-------+
| id | name  |
+----+-------+
|  1 | HCC   |
|  2 | Marry |
|  5 | SMK   |
|  6 | ZZD   |
|  7 | zwt   |
|  8 | MR    |
|  9 | ZL    |
| 10 | ZH    |
+----+-------+
8 rows in set (0.00 sec)

########回滚到保存点,查看数据######

mysql> rollback to pont1
    -> ;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from transaction;
+----+-------+
| id | name  |
+----+-------+
|  1 | HCC   |
|  2 | Marry |
|  5 | SMK   |
|  6 | ZZD   |
|  7 | zwt   |
|  8 | MR    |
|  9 | ZL    |
+----+-------+
7 rows in set (0.00 sec)


##########提交事务,查看数据##########
mysql> commit;
Query OK, 0 rows affected (0.14 sec)

mysql> select * from transaction;
+----+-------+
| id | name  |
+----+-------+
|  1 | HCC   |
|  2 | Marry |
|  5 | SMK   |
|  6 | ZZD   |
|  7 | zwt   |
|  8 | MR    |
|  9 | ZL    |
+----+-------+
7 rows in set (0.00 sec)


这就相当于加了一个断点吗,在保证这一节点之前数据正确后,可以将数据回到这个保存点,即使后边数据损坏了,在提交事务时这部分数据也能保存。release savepoint 就不说了,就是在事务中将相应的保存点去掉。。

在试试SET TRANSACTION。。。。。。首先隔离级别如下:

隔离解别脏读不可重复读幻读
Read UncommittedYYY
Read CommittedNYY
Repeatable(default)NNY
SerializableNN

看了一篇文章很好,自己就不写了。。。。。链接在此。。。

https://www.cnblogs.com/huanongying/p/7021555.html

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值