(一) 事务并发可导致的问题
事务并发大致可以导致一下几个问题:lost update、dirty read、uprepeatable read和phantom read。uprepeatable read还有个特例就是second lost updates problem,即是不同事务中后面的更新操作会覆盖之前事务的更新操作。uprepeatable read和phantom read的区别在于uprepeatable read是有数据更新造成的,而phantom read则是由于新插入数据造成的。
(二)数据库系统的锁的基本原理
数据库本身会提供锁的机制:共享锁、独占锁。select会使事务获取共享锁而delete、insert、update则会使事务获取独占锁。两个事务同时获取共享锁然后执行更新操作即都想获取独占锁时,便会产生死锁。这种锁机制是数据库系统自带的,它会根据事务执行的sql语句,来自动为数据源上锁,它有以下几种颗粒度:
1. 数据库级锁:锁定整个数据库;
2. 表级锁: 锁定一张表;
3. 区域级锁: 锁定数据库的特定区域;
4. 页面级锁: 锁定特定的页面;
5. 键值级锁: 锁定表中带有索引的一行数据;
6. 行级锁: 锁定表中单行数据。
(三) 事务隔离级别
锁控制并发的效果好,但是尽量不要显式的为数据库加锁,而应该首先让数据库自动管理锁。数据库的隔离级别提供了很好的支持。它有四种级别:
1. serializable
2. repeatable read
3. read commited
4. read uncommited
在mysql里可以这样设置隔离级别:
// 单个链接
set transaction isolation level read commited;
// 数据库全局
set global transaction isolation level read commited;
hibernate也可以在配置文件里设置:
hibernate.connection.isolation=2
2 表示 read commited级别,其他的为:1 - read uncommitted、4 - repeatable read、8 - serialized