事务
概念
把一组操作封装到一起,成为了一个共同的执行单元,此时执行整个事务就会避免其他的干涉影响。
事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败。在不同的环境中,都可以有事务。对应在数据库中,就是数据库事务。
基本特性
1、原子性: 事务中的若干个操作,要么全部成功,要么全都不执行 (并不是真的不执行,如果一旦中间某个步骤执行出错,就把前面已经执行完毕的步骤回滚,把原来操作造成的影响进行还原,操作可逆)
2、一致性: 执行事务前后,数据始终处于合法状态,例如转账,减账户余额时,不能把账户减成负数。
3、持久性: 事务一旦执行完毕,对数据的修改就是持久生效(写入磁盘)数据存到磁盘就是持久的,数据存到内存就是不持久的重启就没了。
4、隔离性: 涉及到并发执行事务,多个事务并发执行时,事务之间不能相互干扰(本质就是线程安全问题)
隔离性和并发
隔离性和并发是相悖的
隔离是为了保证数据准确
并发是为了提高事务执行的效率
如果多个事务之间隔离性越强,并发程度就越低,效率越低;
如果多个事务之间隔离性越弱,并发程度就越高,效率越高
虽然两者相悖,但是在不同的应用场景下,对于数据的准确性的要求不一样,可以在满足数据准确性要求的前提下,尽可能的提高并发程度。 涉及到MySQL中的事务隔离级别。
并发执行事务
此处考虑的并发执行多个事务,可以类比成多线程执行一些逻辑
但是此处的”写加锁” “读加锁”不要和sychronized类比
写加锁的意思是:我写代码的时候,大家不能读.但是大家读的时候,我还能写.
读加锁的意思是:大家读的时候我也不能写了.
同时具备写加锁和读加锁=>等同于sychronized
1、脏读
事务A读取了事务B提交之前的数据很可能在B最终提交之后,把这个数据又给改了.于是事务A就产生了脏读.
如果一个事务A正在修改数据,还没有提交,另外一个事务B读取了这里的修改内容,此时这样的事务B的读操作就是脏读,因为事务A在提交数据之前,随时可能又修改了刚才的数据
解决:
给写操作加锁,在写的时候不能读,直到写完提交,将锁释放,才能读取。 A在修改数据的过程中,B尝试读,就会阻塞,一直阻塞到A提交数据之后,B才能读到数据。
引入写加锁,事务的并发程度就降低了,效率就低了,隔离性就提高了。
2、不可重复读
一个事务A在执行过程中,事务B第一次读和第二次读,两次读取到的数据不相同
解决:
上面的脏读,是写的时候不能读,但是在读的时候可以写(修改),现在在写加锁的基础上给读也加锁,意思在读取的时候,不能写
引入读加锁,事务的并发性就更低了,效率也就更低了,隔离性就更高了。
3、幻读
同一个事务中,两次读到的结果集不-一致.,虽然读锁加了之后,读的时候不能改,但是可以新增或者删除记录.
一次事务执行过程中,多行读取到的结果集不一样,(具体的结果是一致的)
解决:
串行化,读的时候不能改,改的时候不能读,这个时候并发性最低,效率最低,但是数据可靠性最高。
语句
start transaction 开启事务,表示接下来的操作都是在同一个事务中。
commit 事务结束,开始正式执行,一旦中间某个步骤执行出错,就会进行回滚。
mysql> select * from accout;
+----+--------------+---------+
| id | name | money |
+----+--------------+---------+
| 1 | 阿里巴巴 | 5000.00 |
| 2 | 四十大盗 | 1000.00 |
+----+--------------+---------+
2 rows in set (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> update accout set money=money-2000 where name = '阿里巴巴';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> update accout set money=money+2000 where name = '四十大盗';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> commit;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from accout;
+----+--------------+---------+
| id | name | money |
+----+--------------+---------+
| 1 | 阿里巴巴 | 3000.00 |
| 2 | 四十大盗 | 3000.00 |
+----+--------------+---------+
2 rows in set (0.00 sec)
假如在执行以上第一句SQL时,出现网络错误,或是数据库挂掉了,
阿里巴巴的账户会减少2000,但是 四十大盗的账户上就没有了增加的金额。
MySQL的隔离级别
MySQL的隔离级别:对隔离性的要求具体多高(隔离性高了,并发程度就低了,数据可靠性高了,效率就低了)
- read uncommitted:
- 允许读取未提交的数据(隔离程度最低,并发性最高,会有脏读问题)
- read committed:
- 只允许读取已经提交的数据,相当于写加锁. (隔离性提高了- -些, 并发性降低了一一些解决了脏读,但是会有不可重复读)
- repeatable read(MySQL的默认隔离级别):
- 给读也加锁. (隔离性又提高了,并发性又降低了,解决了不可重复读,但是会有幻读问题).
- serializable :
- 严格串行化执行. (隔离性性最高,并发最低解决了幻读问题)
SQL语句中显式的指定当前的SQL使用哪种隔离级别.不指定,默认就是repeatable read
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/152968.html