什么是事务?
数据库中的事务是指对数据库执⾏⼀批操作,这些操作最终要么全部执⾏成功,要么全部
失败,不会存在部分成功的情况。
举个例⼦
⽐如A⽤户给B⽤户转账100操作,过程如下:
1.从A账户扣100
2.给B账户加100
如果在事务的⽀持下,上⾯最终只有2种结果:
1. 操作成功:A账户减少100;B账户增加100
2. 操作失败:A、B两个账户都没有发⽣变化
如果没有事务的⽀持,可能出现错:A账户减少了100,此时系统挂了,导致B账户没有加
上100,⽽A账户凭空少了100。事务的⼏个特性(ACID)
原⼦性(Atomicity)
事务的整个过程如原⼦操作⼀样,最终要么全部成功,或者全部失败,这个原⼦性是从最
终结果来看的,从最终结果来看这个过程是不可分割的。
⼀致性(Consistency)
⼀个事务必须使数据库从⼀个⼀致性状态变换到另⼀个⼀致性状态。
⾸先回顾⼀下⼀致性的定义。所谓⼀致性,指的是数据处于⼀种有意义的状态,这种状态
是语义上的⽽不是语法上的。最常见的例⼦是转帐。例如从帐户A转⼀笔钱到帐户B上,
如果帐户A上的钱减少了,⽽帐户B上的钱却没有增加,那么我们认为此时数据处于不⼀
致的状态。
从这段话的理解来看,所谓⼀致性,即,从实际的业务逻辑上来说,最终结果是对的、是
跟程序员的所期望的结果完全符合的
隔离性(Isoladon)
⼀个事务的执⾏不能被其他事务⼲扰。即⼀个事务内部的操作及使⽤的数据对并发的其他
事务是隔离的,并发执⾏的各个事务之间不能互相⼲扰。
持久性(Durability)
⼀个事务⼀旦提交,他对数据库中数据的改变就应该是永久性的。当事务提交之后,数据
会持久化到硬盘,修改是永久性的。
Mysql中事务操作
mysql中事务默认是隐式事务,执⾏insert、update、delete操作的时候,数据库⾃动开启
事务、提交或回滚事务。
是否开启隐式事务是由变量autocommit控制的。所以事务分为隐式事务和显式事务。
隐式事务
事务⾃动开启、提交或回滚,⽐如insert、update、delete语句,事务的开启、
提交或回滚由mysql内部⾃动控制的。
查看变量autocommit是否开启了⾃动提交
mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
1 row in set, 1 warning (0.00 sec)
autocommit为ON表⽰开启了⾃动提交。
显式事务
事务需要⼿动开启、提交或回滚,由开发者⾃⼰控制。
2种⽅式⼿动控制事务:
⽅式1:
语法:
//设置不⾃动提交事务
set autocommit=0;
//执⾏事务操作
commit|rollback;
⽰例1:提交事务操作,如下:
mysql> create table test1 (a int);
Query OK, 0 rows affected (0.01 sec)
mysql> select * from test1;
Empty set (0.00 sec)mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test1 values(1);
Query OK, 1 row affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test1;
+------+
| a |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
⽰例2:回滚事务操作,如下:
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test1 values(2);
Query OK, 1 row affected (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test1;
+------+
| a |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
可以看到上⾯数据回滚了。
我们把autocommit还原回去:mysql> set autocommit=1;
Query OK, 0 rows affected (0.00 sec)
⽅式2:
语法:
start transaction;//开启事务
//执⾏事务操作
commit|rollback;
⽰例1:提交事务操作,如下:
mysql> select * from test1;
+------+
| a |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test1 values (2);
Query OK, 1 row affected (0.00 sec)
mysql> insert into test1 values (3);
Query OK, 1 row affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test1;
+------+
| a |
+------+
| 1 |
| 2 |
| 3 |+------+
3 rows in set (0.00 sec)
上⾯成功插⼊了2条数据。
⽰例2:回滚事务操作,如下:
mysql> select * from test1;
+------+
| a |
+------+
| 1 |
| 2 |
| 3 |
+------+
3 rows in set (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> delete from test1;
Query OK, 3 rows affected (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test1;
+------+
| a |
+------+
| 1 |
| 2 |
| 3 |
+------+
3 rows in set (0.00 sec)
上⾯事务中我们删除了test1的数据,显⽰删除了3⾏,最后回滚了事务。