数据库事务
数据库事务可以这么理解,满足数据库ACID特性的一组操作。我们可以使用COMMIT 命令提交事务,也可以用ROLLBACK 回滚事务。
MySQL 中默认采用自动提交(AUTOCOMMIT)模式。如果不显式使用 START TRANSACTION 语句来开始一个事务,那么每个查询都会被当做一个事务自动提交。
数据库的acid特性
并发导致的问题
-
修改丢失 有两个事务同时一行记录进行修改,其中前面修改的数据被后面修改的数据覆盖了。导致前面修改的数据无效: 这里T1先将数据修改成50,但是之后被T2覆盖,导致T修改无效。 -
脏数据读取 与上面差不多。两个并发的事务,A事务和B事务同时操作了同一行数据,A将数据修改之后,此条数据被B事务读取,之后如果A将事务回滚,而B就读到了无效的“脏数据”。 举个例子:小明给我打1000¥,我查余额时发现我多了1000¥,很开心的打算去买衣服。此时因为银行程序错误,刚刚小明打的钱被回滚了。导致我的账户实际并没有这么多钱,后面我选好衣服后发现账户余额不足。。。 -
不可重复读 是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。(同时操作,事务1分别读取事务2操作时和提交后的数据,读取的记录内容不一致。不可重复读是指在同一个事务内,两个相同的查询返回了不同的结果。 )
事务隔离级别
-
Serializable(串行化) 所有事务一个接着一个的执行,这样可以避免幻读 (phantom read) -
Repeatded Read(可重复读) 所有被 Select 获取的数据都不能被修改,这样就可以避免一个事务前后读取数据不一致的情况。但是却没有办法控制幻读,因为这个时候其他事务不能更改所选的数据,但是可以增加数据,即前一个事务有读锁但是没有范围锁,为什么叫做可重复读等级呢?那是因为该等级解决了下面的不可重复读问题。 -
Read Committed(读已提交) 被读取的数据可以被其他事务修改,这样可能导致不可重复读。也就是说,事务读取的时候获取读锁,但是在读完之后立即释放(不需要等事务结束),而写锁则是事务提交之后才释放,释放读锁之后,就可能被其他事务修改数据。 -
Read uncommited(读未提交) 最低的隔离等级,允许其他事务看到没有提交的数据,会导致脏读。 -
总结 四个级别逐渐增强,每个级别解决一个问题,每个级别解决一个问题,事务级别遇到,性能越差,大多数环境(Read committed 就可以用了)
|