1.丢失更新
两个事务同时修改了同一条数据,则后修改的被保留,先修改的将丢失。
2.脏读(未确认的相关性)
一个事物修改了数据但是没有提交,这时第二个事务读取了这个数据。然后第一个事务回滚,导致读取到了脏数据。
3.不可重复读
发生在一个事务读取两次数据的情况。如,一个事务先读取了一条数据后,另一个事务修改了这条数据,并提交了事务。那么第一个事务再次读取这个数据,读到了被修改的数据。
4.幻读
一个事务先读取记录时,另一个事务增加了记录并且提交。事务一再次读取时就会读取到新增的记录。
事务隔离级别描述:
READ UNCOMMITTED:幻读,不可重复读和脏读均允许;
READ COMMITTED:允许幻读和不可重复读,但不允许脏读;
REPEATABLE READ:允许幻读,但不允许不可重复读和脏读;
SERIALIZABLE:幻读,不可重复读和脏读都不允许;
ORACLE默认的是 READ COMMITTED。
隔离级别越高,并发性越差
这里还有一篇文章,讲的更详细,放在这里
ISOLATION_DEFAULT: 使用底层数据库预设的隔离层级
ISOLATION_READ_COMMITTED: 允许事务读取其他并行的事务已经送出(Commit)的数据字段,可以防止Dirty read问题
ISOLATION_READ_UNCOMMITTED: 允许事务读取其他并行的事务还没送出的数据,会发生Dirty、Nonrepeatable、Phantom read等问题
ISOLATION_REPEATABLE_READ: 要求多次读取的数据必须相同,除非事务本身更新数据,可防止Dirty、Nonrepeatable read问题
ISOLATION_SERIALIZABLE: 完整的隔离层级,可防止Dirty、Nonrepeatable、Phantom read等问题,会锁定对应的数据表格,因而有效率问题
具体知识请看这篇文章,进一步了解spring事务请看这篇文章。
MySql悲观锁、乐观锁
悲观锁在数据被读取时,启动数据库级别的锁,使数据只能被访问一次(主键和索引都会影响数据库的访问级别)。
乐观锁使用version或时间戳存储一个字段,当提交修改时,如果发现和读取时的版本号不一样,则提交不会成功。