假设我们有事务t1,它在SERIABLIZABLE级别的表中插入一行。现在有另一个事务t2不在SERIABLIZABLE级别,它通过select * from table_foo
从同一个表中选择所有行我的问题是在t1提交/释放锁之前,t2会看到t1行插入吗?
答案 0 :(得分:1)
我的问题是在t1提交/释放锁之前,将t2看到该行 按t1插入?
t2看到的内容完全取决于t2的隔离级别。它与t1的隔离级别无关。
要查看其工作原理,请打开两个终端窗口,并建立两个与MySQL数据库的连接。假设表“test”存在,并且有两行。
Term 1 Term 2
set transaction isolation level serializable;
set transaction isolation level read uncommitted;
select count(*) as num_rows from test;
+----------+
| num_rows |
+----------+
| 2 |
+----------+
1 row in set (0.00 sec)
start transaction;
insert into test values
('2013-01-02 08:00', '2013-01-02 08');
select count(*) as num_rows from test;
+----------+
| num_rows |
+----------+
| 3 |
+----------+
1 row in set (0.00 sec)
rollback;
select count(*) as num_rows from test;
+----------+
| num_rows |
+----------+
| 2 |
+----------+
1 row in set (0.00 sec)
为了确保术语2 不会看到术语1的INSERT语句中的未提交行,直到它们被提交,除了在术语2中使用READ UNCOMMITTED之外,还要使用任何隔离级别。
答案 1 :(得分:0)
假设T1在T2之前执行; T2不会看到行,因为T2等待T1。
当T1开始执行时,它会锁定表以确保最大隔离级别,这意味着在T1完成之前,该表上不会执行任何其他事务。
如果任何其他事务尝试使用该表(在本例中为T2),则必须等待。
因此,T1和T2永远不会同时执行(同时)。 e.g:
T2等待T1
当T1完成T2执行
T2将看到T1插入的行
(评论区太长了) 是的,如果你真的需要以一种有效的方式执行每个事务,那么可以选择将SERIALIZABLE设置为数据库的隔离级别。
理论上,每个事务应该独立执行(为了实现ACID属性的I),但实际上这没有多大意义。这完全取决于性能问题。高并发应用程序的数据库无法以这种方式正确执行。
这个想法是在隔离和性能之间实现平衡。当隔离级别降低时(例如,通常是默认隔离级别的COMMITTED READ),可能会出现一些问题:丢失更新,不可重复读取,幻读。通常这种风险是可以接受的,并且只有在某些必须处理这些情况的交易中才能控制隔离水平。