事物的特性
原子性:事务中包含的逻辑,不可分割
一致性:事务执行前后,数据完整性
隔离性:事务在执行期间不应该受到其他事务的影响
持久性:事务执行成功,数据持久化保存
隔离级别:引发的问题
查看隔离级别:select @@tx_isolation
Read Uncommitted [读未提交] :一个事务读到另外一个事务还未提交的数据,引发脏读问题
set session transaction isolation level read uncommitted
Read Committed [读已提交]:Oracle默认级别,提交了之后数据才受到影响,说到底还是受到影响了,引发不可重复读问题
set session transaction isolation level read committed
Repeatable Read [重复读]:mysql默认级别,锁住满足条件的记录,没锁住的相近的记录,引发了幻读的问题
set session transaction isolation level read Repeatable Read
Serializable [可串行化]:后开启的事务要等先开启的时候提交,讲求先来后到,引发了效率低的问题
set session transaction isolation level read serializable
由隔离级别不够引发的安全问题(注意是事务)
读:脏读、不可重复读、幻读
脏读:一个事务读到另外一个事务未提交的数据(隔离级别读未提交)
不可重复读:一个事务读到了另外一个事务提交的数据,造成前后两个查询不一致(破坏隔离级别)
幻读:一个事务读到了另一个事务已提交的插入的数据,导致多次查询结果不一致
注意:不可重复读和幻读的区别
不可重复读的重点是修改:
同样的条件, 你读取过的数据, 再次读取出来发现值不一样了
幻读的重点在于新增或者删除
同样的条件, 第1次和第2次读出来的记录数不一样
当然, 从总的结果来看, 似乎两者都表现为两次读取的结果不一致.
但如果你从控制的角度来看, 两者的区别就比较大
对于前者, 只需要锁住满足条件的记录
对于后者, 要锁住满足条件及其相近的记录
写:丢失更新
丢失更新:后面事务B的更新直接覆盖了前面事务A的更新,即使回滚也是回到事务B所认知的记录
解决办法
悲观锁:一开始就认为一定会出现丢失
用排他锁for update ,如果A事务使用了排他锁之后,其他事务的界面会卡住。
select * from account for update;
乐观锁:认为很少由丢失问题
在数据库表中使用一个字段作为修改与否的标记,更新时通过对比标记判断是否有被修改