事务(TRANSACTION)(在开发中必不可少的操作)
1.是作为单个逻辑工作单位执行的一系列操作;
2.多个操作作为一个整体向系统提交,要么都执行、要么都不执行;
3.事务是一个不可分割的工作逻辑单元。
【转账过程就是一个整体
他需要两天UPDATE语句,这两条语句是一个整体
】
事务的四个属性(ACID)
原子性(Atomicity):事务是一个完整的操作,事务的各步操作是不可分的(原子的),要么都执行,要么都不执行;
一致性(Consistency):当事务完成时,数据必须处于一致状态;
隔离性(Isolation):并非事务之间彼此隔离、独立,它不应该以任何方式依赖或影响其他事务;
持久性(Durability):事务完成后,它对数据库的修改被永久保持。
创建事务:MySQL中支持事务的存储引擎有InnoDB和BDB
开始事务: BEGIN;
或START TRANSACTION;
提交事务 COMMIT;
撤销事务 ROLLBACLK;
#解决sql语句执行时代码:1055错误
> select version();
> @@SQL_mode ; SET sql_mode=(select
> replace(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
#清空整张表中的数据,并重置表结构:
TRUNCATE <表名>;
**
多条事务用法
**
在MySQL中,默认情况下,每条DML操作的语句都是一条单独事务。
每次执行DML后,都会自动提交事务。(所以一条语句不会构成一个完整的事务)
select @@autocommit;
可以通过关闭自动提交解决:
set autocommit=0;
利用以上操作可以执行多条DML语句;
也可以通过begi或者start transaction开启事务:
开启事务
start transaction;
事务代码块:增、删、改、查语句;
提交事务,将事务代码库的语句的动作持久化到数据库;
commit;
撤销之前的操作(回滚):
rollback;
事务的隔离级别(什么是脏读,不可重复读,幻读)
不同的数据库默认具有不同的隔离级别,不同的隔离级别,在并发事务可能会出现不同的问题,大多数数据库支持此种隔离级别。
1.未提交独(Read uncommitted)
2.已提交读(Read committed),Oracle数据库的默认隔离级别;
2.可重复读(repeatable Read),MySQL数据库的隔离级别;
3.串行化(Serializable),所有的并发事务按照顺序执行,类似于排队的概念,好处是安全,坏处是效率低,
在实际开发过程中,往往需要不同的业务场景修改事务的隔离级别。
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
未提交读 | 可能 | 可能 | 可能 |
已提交读 | 不可能 | 可能 | 可能 |
可重复读 | 不可能 | 不可能 | 可能 |
串行化 | 不可能 | 不可能 | 不可能 |
#查看当前数据库的事务的隔离级别
select @@tx_isolation;
#设置read uncommitted 级别
set session transaction isolation level read uncommitted
#设置read committed 级别
set session transaction isolation level read committed
#设置repeatable read 级别
set session transaction isolation level repeatable read
#设置serializable 级别
set session transaction isolation level serializable
什么是脏读
通俗的讲,一个事务在处理过程中读取了另外一个事务为提交的数据。(读未提交数据)
你都还么有提交,我就读到了你刚操作的数据,事务回滚导致数据脏。
操作顺序 | 事务A | 事务B |
---|---|---|
1 | select baliance from account where id=1(结果为1) | |
2 | update account set balanve=blance+500 where id =1(结果为501) | |
3 | select baliance from account where id=1(结果为501) | |
4 | rollback | |
5 | select baliance from account where id=1(结果为1) |
不可重复读
通俗的讲,一个事务范围内,多次查询某个数据,却得到不同的结果。
与脏读的区别:脏读是读到未提交的数据,而不可重复读读到的是已经提交的数据,实际上是违反事务的一致性。
幻读
在Repeatable Read隔离级别下,一个事务可能会遇到幻读的问题。
在事务A读取搜索条件匹配若干行。事务B插入或删除等方式来修改事务A的结果集,然后提交。
1.A事务查询了tab表,得到了1条数据;
2.B事务向tab表插入了一条数据并提交,查看数据库表发现表中总共2条数据;
3.A事务再次执行第一步相同的查询语句是,还是只有一条数据,此时如果执行修改或者删除第二步B事务插入的数据是,又是能成功的,这种情况即为幻读。
悲观锁和乐观锁
悲观锁通常是有数据库底层实现,比如for update;
乐观锁,由我们自己设计,通常在表中增加一个version版本号的字段。
1.每次在查询数据时,首先比对查询的版本号和数据库中版本号是否相同,如果不同,则说明之前查询到的数据已经过期(被别人修改过)
若干版本号相同,则修改业务数据,并且迭代版本号(version = version+1)
乐观锁是工作中比较常见的一种锁机制,这些机制能够非常有效的解决事务并发是对数据的安全性的影响。