1、什么是事务
事务就是一堆的sql语句加上逻辑判断
2、事物的四大特性(ACID)
原子性:整个事务作为一个整体要么都成功要么所有的都失败
一致性:同一个事务相同的条件,不同的时间要得到相同的结果
隔离性:两个事务之间在未提交之前只能看到自己修改的数据,不能看到对方修改的数据
持久性:持久化到磁盘
3、当一个事务执行时,不可避免的会出现以下四个问题:
脏读
事务T1可以读取到事务T2未提交的数据
不可重复读
同一个事务,同样的条件,前后可能得到不同的数据;
示例:
在事务1中,Mary 读取了自己的工资为1000,事务没结束
select salary from employee empId =‘Mary’;
在事务2中,财务人员修改了Mary的工资为2000,并提交了事务
update employee set salary = 2000;
commit;
在事务1中,Mary 再次读取自己的工资时,工资变为了2000
幻读
同一个事务,同样的条件,前后可能得到不同的数据;
示例:
在事务1中,读取所有工资为1000的员工(10人)
Select * from employee where salary =1000;
在事务2中,向employee表插入了一条员工记录,工资也为1000 ,并提交
Insert into employee(empId,salary) values(‘zs’,1000);
commit;
事务1再次读取所有工资为1000的员工(11人)
Select * from employee where salary =1000;
幻读和不可重复读结果是一致的,但是不可重复读侧重的是修改,而幻读侧重的是新增和删除。
幻读的解决方式是对表加表锁解决。
不可重复读的解决方式可以对特定的行加锁解决。
丢失更新
一个事务的修改覆盖了另一个事务所做的修改
示例:以下操作按顺序执行
事务1读取4号球员的罚款额,为50
事务2读取4号球员的罚款额,也为50
事务1把罚款额增加25,并提交
Update penalties set amount=amount + 25;
Commit;
事务2把罚款额增加30,并提交
Update penalties set amount=amount + 30;
Commit;
此时,事务1认为最新的罚款额为75,但是实际上是80,事务1所做的更新操作被事务2覆盖掉了。事务1的更新丢失了
4、 事务的四个隔离级别:
未提交读
READ-UNCOMMITTED
1、发生了脏读
2、发生了不可重复读
3、发生了幻读
4、发生了丢失更新
已提交读
READ-COMMITTED
1、避免了脏读
2、发生了不可重复读
3、发生了幻读
4、发生了丢失更新
可重复读
REPEATABLE-READ
1、避免了脏读
2、避免了不可重复读
3、避免了幻读
4、发生了丢失更新
串行化
SERIALIZABLE
1、避免了脏读
2、避免了不可重复读
3、避免了幻读
4、避免了丢失更新
事务的隔离级别建议在创建数据库时,在配置文件中指定,最好后期不要修改
MySQL允许客户端会话显式地获得一个表锁,以防止其它会话修改表
语法:
LOCK TABLES tbl_name [[AS] alias] lock_type [, tbl_name [[AS] alias] lock_type] …
其中,锁类型lock_type:
READ [LOCAL] | [LOW_PRIORITY] WRITE
对于innodb引擎, READ [LOCAL] = READ , LOW_PRIORITY被废弃
READ:当前会话和其它会话都可以读表,但是不能修改表
WRITE:当前会话可以读写表,但是其它会话既不能读也不能写
UNLOCK TABLES
释放当前会话持有的所有表锁