事务要解决的是数据库的并发问题,一般数据库会出现以下几种并发问题:
- 脏读 :对于俩个事务T1、T2,T1读取了已经被T2更新但还没有被提交的字段,之后,若T2回滚,T1读取的内容就是临时且无效的。
- 不可重复读 :对于俩个事务T1、T2,T1读取了一个字段,然后T2更新了该字段,之后,T1再次读取同一个字段,值就不同了。
- 幻读 :对于俩个事务T1、T2,T1从一个表中读取了一个字段,然后T2在该表中插入一些新的行,之后,如果T1再次读取同一个表,就会多出几行。
为了解决以上情况,数据库提供了四种事务隔离级别:
隔离级别 | 描述 |
READ UNCOMMITTED(读未提交数据) | 允许事务读取未被其它事务提交的变更。脏读、不可重复读和幻读的问题都会出现。 |
READ COMMITED(读已提交数据) | 只允许事务读取已被其它事务提交的变更。可以避免脏读,但是不可重复读和幻读问题仍然可能出现。 |
REPEATABLE READ(可重复读) | 确保事务可以多次从一个字段中读取相同的值,在这个事务持续期间,禁止其它事务对这个字段进行更新,可以避免脏读和不可重复读,但幻读的问题依然存在。 |
SERIALIZABLE(串行化) | 确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其它事务对该表执行插入、更新和删除操作。所有的并发问题都可以避免,但是性能十分低下。 |
- Oracle支持的2中事务隔离级别为:READ COMMITED,SERIALIZABLE。其默认隔离级别为READ COMMITED。
- Mysql支持4种事务隔离级别。Mysql默认的事务隔离级别为:REPEATABLE READ。
事务的四大特性(ACID):
- 原子性:事务是一个整体,从开始到提交;
- 一致性:事务中的所有操作结果一致,要么全部成功,要么就全部失败;
- 隔离性:多个事务之间互不干扰,互相隔离。
- 持久性:事务一单提交或者回滚,其结果将不能在改变,具有持久能力。
在MySql中设置隔离级别的方式:
- MySQL 的事务隔离是在 MySQL. ini 配置文件里添加的,在文件的最后添加:transaction-isolation = REPEATABLE-READ
- 通过sql语句进行设置:
1、查看当前的隔离级别:
SELECT @@tx_isolation;
2、设置当前mySQL连接的隔离级别:
set transaction isolation level read committed;
3、设置数据库系统的全局的隔离级别:
set global transaction isolation level read committed;