数据库事务与锁
事务隔离级别
- 脏读
事务中可以读到未提交事务修改的数据。 - 不可重复读
事务中先后读取同一条记录,值不相同的现象。例如:A事务中读取一条数据,其值为1,B事务修改了其值为2,B事务提交后,A事务再次读取这条数据,其值变成了2。 - 幻读
事务中先后以某条件读取一张表,记录数不同的现象。
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
read uncommitted | √ | √ | √ |
read committed | × | √ | √ |
repeatable read | × | × | √ |
serialized | × | × | × |
??实际上,SELECT查询看到的是一个在查询开始运行的瞬间该数据库的一个快照。不过SELECT可以看见在它自身事务中之前执行的更新的效果,即使它们还没有被提交。
2.可重复读(repeatable read) ??可重复读隔离级别只看到在事务开始之前被提交的数据,不过,查询能够看见在它的事务中之前执行的更新,即使它们还没有被提交。
??这个级别与读已提交不同之处在于,一个可重复读事务中的查询看到 事务中第一个非事务控制语句开始时的一个快照, 而不是事务中当前语句开始时的快照。
??当处于可重复读事务中时,如果要修改的记录,与事务开始时的数据快照不一致时,修改该记录会发生ERROR: could not serialize access due to concurrent update异常,导致回滚。
3.可序列化(serializable) 【数据库事务与锁】??待补充
试验(基于Postgresql) 试验1 事务A隔离级别:read committed
事务B隔离级别:read committed
A:
begin transaction isolation level read committed;
update usr set name = 'admin' where id = 1;
//update语句在这条记录上增加了共享锁,其他事务可读不可写B:
begin transaction isolation level read committed;
select * from usr where id = 1;
//可以读
+----+-----------+
| id | name|
+----+-----------+
|1 | admin1111 |
+----+-----------+
update usr set name = 'admin1111' where id = 1;
//不可修改,发生了阻塞,等待上一事务结束A:
commit;
B:
//阻塞停止,update生效
commit;
select * from usr where id = 1;
+----+-----------+
| id | name|
+----+-----------+
|1 | admin1111 |
+----+-----------+
试验2 事务A隔离级别:repeatable read
事务B隔离级别:repeatable read
2.1 事务提交
A:
begin transaction isolation level repeatable read;
update usr set name = 'AAA' where id = 1;
//加共享锁B:
begin transaction isolation level repeatable read;
select * from usr where id =1;
+----+-----------+
| id | name|
+----+-----------+
|1 | admin1111 |
+----+-----------+
update usr set name = 'BBB' where id = 1;
//不可修改,发生了阻塞,等待上一事务结束A:
commit;
B:
///阻塞停止,更新失败
ERROR:could not serialize access due to concurrent updateselect * from usr where id =1;
+----+------+
| id | name |
+----+------+
|1 | AAA|
+----+------+
2.2事务回滚
A:
begin transaction isolation level repeatable read;
update usr set name = 'AAA' where id = 1;
//加共享锁
B:
begin transaction isolation level repeatable read;
select * from usr where id =1;
+----+-----------+
| id | name|
+----+-----------+
|1 | admin1111 |
+----+-----------+
update usr set name = 'BBB' where id = 1;
//不可修改,发生了阻塞,等待上一事务结束A:
rollback;
B:
///阻塞停止,update生效
select * from usr where id =1;
+----+------+
| id | name |
+----+------+
|1 | B|
+----+------+
参考资料:http://www.postgres.cn/docs/9.5/transaction-iso.html
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- Docker应用:容器间通信与Mariadb数据库主从复制
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量
- 第326天
- Shell-Bash变量与运算符
- 逻辑回归的理解与python示例
- Guava|Guava RateLimiter与限流算法
- 我和你之前距离
- CGI,FastCGI,PHP-CGI与PHP-FPM
- 原生家庭之痛与超越