1.MySQL数据库的四大特性:
原子性(Atomicity)
原子性是指,一个事务是一个不可分割的工作单位,事务中的所有操作,要么全部成功,要么全部失败回滚。举例:拿转账来说,用户A给用户B转账,至少要包含两个操作,用户A钱数减少,用户B钱数增加,增加和减少的操作要么全部成功,要么全部失败,是一个原子操作。
一致性(Consistency)
一致性是指,一个事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。举例:拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来还得是5000,这就是事务的一致性。
隔离性(Isolation)
隔离性是指,一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据,对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。就是要达到这样一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。
持久性(Durability)
持久性是指,一个事务一旦被提交,它对数据库中数据的改变就是永久性的。接下来的其他操作或故障不应该对其有任何影响。
2. 并发问题
1. 脏读(dirty read):A事务读取了B事务尚 未提交 的更改数据。
2. 不可重复读(unrepeatable read):A事务读取了B事务 已提交 的更改数据(A事务内,多次查询返回结果不同)
3. 幻读(phantom read):A事务读取了B事务提交的 新增 数据,两次统计数据不同。(一般发生在统计计数)
4. 第一类丢失更新(无任何隔离级别,不会发生)
A事务的回滚操作,导致A的旧数据覆盖了B事务已经提交的数据。
5. 第二类丢失更新(操作不当会发生)
多个事务同时更新一行数据
A事务提交覆盖了B已经提交的数据
第二类更新丢失的问题,如果数据库用户使用方式不对,是有可能出现问题的。
通常有两种方式可以解决这个问题:
#悲观锁
#悲观锁就是锁定要更新的这一行,然后在事务提交之前不让其他事务对该行数据做任何操作
#直至释放行锁
select money from account where id=10 for update
money = money + 100
update account set money = money where id =10
#乐观锁
#乐观锁是在并发的表上加一个version字段,更新的时候只有版本号大于当前版本号才能更新成功
select money,version from account where id=10 for update
money = money + 100
version = version + 1
update account set money = money where id =10 and version > version
3. 数据库的隔离级别
- Read uncommitted (未提交读):最低级别,任何情况都无法保证(脏读、不可重复读、幻读)。
- Read committed (已提交读):可避免脏读的发生。
- Repeatable read (可重复读):可避免脏读、不可重复读的发生。
- Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
MySQL默认RR, Oracle默认RC
注意:MySQL中RR采用的是Next-key lock 算法