我目前正在阅读《高性能MySQL,第二版》,试图理解MySQL中的事务隔离。
下面是他们对这两个事务隔离级别的解释。
阅读提交
大多数数据库系统(但不是MySQL!)的默认隔离级别是READ COMMITTED。它满足了之前使用的隔离的简单定义:事务将只看到在开始时已经提交的事务所做的更改,并且在它提交之前,它的更改不会对其他人可见。这个级别仍然允许所谓的不可重复读取。这意味着您可以运行相同的语句两次,看到不同的数据。
可重复读取
可重复读取解决了未提交读取所带来的问题。它保证了一个事务读取的任何行在同一个事务的后续读取中“看起来相同”,但是理论上它仍然允许另一个棘手的问题:幻像读取。简而言之,当您选择某个范围的行,另一个事务向该范围插入一个新行,然后您再次选择同一范围时,就会发生幻像读取;然后,您将看到新的“幻影”行。InnoDB和Falcon用多版本并发控制解决了幻像读取问题,我们将在本章后面解释。可重复读取是MySQL的默认事务隔离级别。InnoDB和Falcon存储引擎支持这种设置,您将在第6章中了解如何更改这种设置。其他一些存储引擎也是如此,但选择取决于引擎。
问题:
1-在READ COMMITTED中,如果这个隔离级别意味着事务只能看到由其他事务提交的更改,为什么在同一个事务中,如果您运行相同的语句,您可以看到不同的结果?这是否意味着以下内容?
START TRANSACTION;
SELECT balance FROM checking WHERE customer_id = 10233276;
UPDATE checking SET balance = balance - 200.00 WHERE customer_id = 10233276;
# >>> NEXT I MUST SEE THE NEW BALANCE, OR I AM WRONG ?
SELECT balance FROM checking WHERE customer_id = 10233276;
COMMIT;
2-在REPEATABLE READ中,如果这个隔离级别允许幻像读取,为什么它会保证事务读取的任何行在后续读取中“看起来相同”?幻像读取不反驳这个级别的保证吗?
在 READ COMMITED 中,无论您是否在事务中,您都会看到已提交的信息,因此不能保证信息中的集成,因为它可以多次更改。取而代之的是可重复的读取,它禁止您在交易中修改(更新)信息(完整性),但您可以添加信息(插入...
根据我的理解,假设在开始此交易之前余额为 1000。
启动事务并将其更新为“balance=balance-200”后,如果在事务中再次运行select语句,则结果如下-
>
若隔离级别为READ COMMITTED,那个么您将看到结果为800。
如果隔离级别是可重复读取,那么您将看到结果为1000。
http://ronaldbradford.com/blog/understanding-mysql-innodb-transaction-isolation-2009-09-24/
可重复阅读
第一场会议:
MariaDB [test]> DROP TABLE IF EXISTS transaction_test;
Query OK, 0 rows affected (0.22 sec)
MariaDB [test]> CREATE TABLE transaction_test(
-> id INT UNSIGNED NOT NULL AUTO_INCREMENT,
-> val VARCHAR(20) NOT NULL,
-> created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-> PRIMARY KEY(id)
-> ) ENGINE=InnoDB DEFAULT CHARSET latin1;
Query OK, 0 rows affected (0.29 sec)
MariaDB [test]>
MariaDB [test]> INSERT INTO transaction_test(val) VALUES ('a'),('b'),('c');
Query OK, 3 rows affected (0.08 sec)
Records: 3 Duplicates: 0 Warnings: 0
MariaDB [test]> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
MariaDB [test]> SELECT * FROM transaction_test;
+----+-----+---------------------+
| id | val | created |
+----+-----+---------------------+
| 1 | a | 2016-04-01 10:09:33 |
| 2 | b | 2016-04-01 10:09:33 |
| 3 | c | 2016-04-01 10:09:33 |
+----+-----+---------------------+
3 rows in set (0.00 sec)
MariaDB [test]> select sleep(50);
然后 user2 运行下一个代码:
MariaDB [test]> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
MariaDB [test]> INSERT INTO transaction_test(val) VALUES ('x'),('y'),('z');
commit;
然后是用户1
MariaDB [test]> SELECT * FROM transaction_test;
+----+-----+---------------------+
| id | val | created |
+----+-----+---------------------+
| 1 | a | 2016-04-01 10:09:33 |
| 2 | b | 2016-04-01 10:09:33 |
| 3 | c | 2016-04-01 10:09:33 |
+----+-----+---------------------+
3 rows in set (0.00 sec)
MariaDB [test]>
已提交读取
用户1
SET SESSION tx_isolation='READ-COMMITTED';
TRUNCATE TABLE transaction_test;
INSERT INTO transaction_test(val) VALUES ('a'),('b'),('c');
MariaDB [test]> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
MariaDB [test]> select sleep(60);
然后 user2 运行下一个代码:
MariaDB [test]> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
MariaDB [test]> INSERT INTO transaction_test(val) VALUES ('x'),('y'),('zwfwfw');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
MariaDB [test]> commit;
然后用户1完成查询:
MariaDB [test]> SELECT * FROM transaction_test;
+----+--------+---------------------+
| id | val | created |
+----+--------+---------------------+
| 1 | a | 2016-04-01 10:28:08 |
| 2 | b | 2016-04-01 10:28:08 |
| 3 | c | 2016-04-01 10:28:08 |
| 4 | x | 2016-04-01 10:29:00 |
| 5 |
y | 2016-04-01 10:29:00 |
| 6 | zwfwfw | 2016-04-01 10:29:00 |
+----+--------+---------------------+
6 rows in set (0.00 sec)
问题内容: 我发生了繁重的数据库操作,这使我的数据库增加了大约10,000条记录。由于这可能需要很长时间,因此最好使用事务。 现在,我在事务内部进行了一些读取操作,并且由于直到endTransaction才提交插入操作,因此不会获取这些记录。我听说过一种叫做“事务隔离级别”的东西,它使我们也可以读取脏的(未提交的)记录。任何想法如何做到这一点? 问题答案: 我发现默认情况下,您将能够读取尚未提交的
问题内容: 从这个甲骨文的Java教程: 当事务A检索行,事务B随后更新该行,事务A随后再次检索同一行时,将发生不可重复的读取。事务A两次检索同一行,但看到不同的数据。 脏读和不可重复读之间有什么区别?是不是同一回事?由于其他人的更新而阅读错误的结果? 提前致谢。 问题答案: 完全相同的页面解释了什么是脏读: 访问尚未提交的更新值被视为脏读,因为该值可能会回滚到其先前的值。如果读取的值稍后会回滚,
那么,有没有其他方法来获得特定的键:值?
不可重复读取和幻像读取有什么区别? 我已经阅读了维基百科上的隔离(数据库系统)文章,但我有一些疑问。在下面的示例中,会发生什么:不可重复读取和幻像读取? ####交易A # # # #输出: ####交易B ####交易A 另一个疑问是,在上面的例子中,应该使用哪个隔离级别?为什么?
pyspark新手,希望将csv文件读取到数据帧。似乎不能让人读。有什么帮助吗? ()中的Py4JJavaError回溯(最近一次调用)----
有一系列关于Kafka交易和一次性交付的优秀文章 在其中一篇文章中,作者谈到了消费者: 因此,在消费者端,您有两个选项来读取事务性消息,通过“isolation.level”消费者配置来表示: read_committed:除了读取不属于事务的消息外,还可以在事务提交后读取属于事务的消息。 read_uncommitted(读取未提交):按偏移顺序读取所有消息,而无需等待事务提交。此选项类似于Ka