首页 数据库 mysql教程 数据库中的隔离级别和锁机制(包含MySQL的测试)

数据库中的隔离级别和锁机制(包含MySQL的测试)

Jun 07, 2016 pm 05:12 PM

ANSI/ISO SQL92标准定义了一些数据库操作的隔离级别:一个更新数据库的事务A在未commit的情况下,另一个事务B正在读取事务A更新的

ANSI/ISO SQL92标准定义了一些数据库操作的隔离级别:

1        未提交读(read uncommitted)

2        提交读(read committed)

3        重复读(repeatable read)

4        序列化(serializable)

锁机制:

   共享锁:其他事务可以读,但不能修改。

   排他锁:其他事务不能读取。

锁粒度:一般分为:行锁、表锁、库锁

解释:

 1 未提交读(read uncommitted)

         一个更新数据库的事务A在未commit的情况下,另一个事务B正在读取事务A更新的记录,会产生脏读现象,这是因为A事务在开启 DB Transaction后,做一些DML操作时,记录会保存在内存中,这时B事务读取了A事务提交在内存中的数据,,产生了脏读。

2 提交读(read committed)

        数据的修改只有在commit之后,才回被读取。和1 相反。

3 重复读(repeatable read)

      当数据库隔离级别设置成 repeatable read后,事务A中的select 的过程中事务B可以修改A读取部分的数据,当A第2次执行同样的sql时,返回和上次相同的数据 ,消除不可重复读。

    注:个人认为只是应为A事务采用这种隔离级别后,读取的是数据库在事务开始时间点的映象,在这个时间点后的所有操作都不会对A事务中的查询产生影响,依据是本文后续的实验,如果有疑问,请指出。

4 序列化(serializable)

      当数据库隔离级别设置成Serializeable后,事务A中的select 会以共享锁锁定相关的数据(在select 返回的数据结果集),这些数据不可以被修改(可以被读取),若事务B对这些数据做UPDATE操作,会处于等待状态,消除幻读。

     注:事务B可以UPDATE 事务A中为锁定的数据,后面的实验可以证明。

     

实验:(Mysql command line client  测试前记得用 set autocommit=off; 将自动提交关闭)

查看数据库默认隔离级别 mysql> SELECT @@global.tx_isolation;     

查看当前会话隔离级别  mysql> SELECT @@tx_isolation;


修改数据库默认隔离级别 mysql> set global transaction isolation level read committed;


修改当前会话隔离级别 mysql> set session transaction isolation level read committed;


1 read uncommitted 测试

   开启两个MySql Command Line Client  A B,将A设置为 read uncommitted ,B 为默认的 repeatable read ;

   set session transaction isolation level read uncommitted;

  通过B向数据库表中插入一条记录,但是不提交事务

  insert into test.user (user_id,name,age) values(4,'fangpin6',25);

 在A中执行 select * from test.user; 会看到这条新插入的记录,说明A用read uncommitted的隔离级别产生了脏读的问题。

2 read committed 测试

   场景同测试1,将A的隔离级别设定为 read committed(mysql> set session transaction isolation level read committed),同样用 select * from test.user; 没有显示B插入的记录。在B中提交数据(mysql> commit;)后,A中显示了B插入的数据。这就说明了A用read committed 不会产生脏读现象。

3 repeatable read 测试

   这部分测试使用了java客户端连接MySql,具体代码如下:

 public static void getResult() throws Exception {
Thread t = new Thread(new MySqlTest().new ThreadTest());
t.start();
Connection mySqlCon = getConn();//获取数据库连接
mySqlCon.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);//设置隔离级别
mySqlCon.setAutoCommit(false);
String sql = " select * from test.user where user_id in( 1 ,3,2,8) ";
printResult(mySqlCon, sql);//打印输出结果
t.sleep(20000); //睡眠20秒(在此过程中 更新数据 update test.user set where user_id = 1 )(1)
System.out.println(" thread sleep finashed ");
String sql2 = " select * from test.user where user_id in(1,3, 2,8) ";
printResult(mySqlCon, sql2);
String sql3 = " select * from test.job";
printResult(mySqlCon, sql3);
mySqlCon.commit();
}

     首先我们将事务隔离级别设置成TRANSACTION_REPEATABLE_READ 就是对应数据库中的repeatable read,然后开始查询USER_ID为 1,2,3,8的USER

表中的数据,在线程挂起的时候(1)处,通过MySql客户端(可以认为是事务B)去更新USER表中USER_ID为1,2的数据,同时更新表JOB的数据。线程继续执行后,打印出USER表为更新前的数据,JOB表为更新前的数据,事务B的操作没有影响的事务A。

   由上述结论推断出:repeatable read 隔离级别是在事务A开始的时间点,读取数据库的映象。

4 serializable 测试

   和3用相同的测试代码,将隔离级别改为mySqlCon.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);//设置隔离级别

TRANSACTION_SERIALIZABLE 对应数据库的serializable 。


  通过事务B在(1)处执行更新表JOB数据、更新表USER where USER_ID In (4,5)、更新表USER where USER_ID In (1,2),在B事务执行过程中,前两个sql执行正常,更新 USER_ID in (1,2)的操作处于等待状态,在事务A结束后,事务B也能正常结束。同时事务A输出的结果包含了B的修改结果。

 由上述实验推断出:serializable 隔离级别是在事务A开始后,对事务A中以扫描到的数据做共享锁,事务B如果要修改这部分加锁的数据,就需要等待A结束。如果在A还没有扫描到(后续会扫描到)某些数据时,事务B已经对这些数据做了修改,那么A将扫描到最新数据(B修改后的数据)

linux

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何使用Alter Table语句在MySQL中更改表? 如何使用Alter Table语句在MySQL中更改表? Mar 19, 2025 pm 03:51 PM

本文讨论了使用MySQL的Alter Table语句修改表,包括添加/删除列,重命名表/列以及更改列数据类型。

说明InnoDB全文搜索功能。 说明InnoDB全文搜索功能。 Apr 02, 2025 pm 06:09 PM

InnoDB的全文搜索功能非常强大,能够显着提高数据库查询效率和处理大量文本数据的能力。 1)InnoDB通过倒排索引实现全文搜索,支持基本和高级搜索查询。 2)使用MATCH和AGAINST关键字进行搜索,支持布尔模式和短语搜索。 3)优化方法包括使用分词技术、定期重建索引和调整缓存大小,以提升性能和准确性。

如何为MySQL连接配置SSL/TLS加密? 如何为MySQL连接配置SSL/TLS加密? Mar 18, 2025 pm 12:01 PM

文章讨论了为MySQL配置SSL/TLS加密,包括证书生成和验证。主要问题是使用自签名证书的安全含义。[角色计数:159]

哪些流行的MySQL GUI工具(例如MySQL Workbench,PhpMyAdmin)是什么? 哪些流行的MySQL GUI工具(例如MySQL Workbench,PhpMyAdmin)是什么? Mar 21, 2025 pm 06:28 PM

文章讨论了流行的MySQL GUI工具,例如MySQL Workbench和PhpMyAdmin,比较了它们对初学者和高级用户的功能和适合性。[159个字符]

您如何处理MySQL中的大型数据集? 您如何处理MySQL中的大型数据集? Mar 21, 2025 pm 12:15 PM

文章讨论了处理MySQL中大型数据集的策略,包括分区,碎片,索引和查询优化。

如何使用Drop Table语句将表放入MySQL中? 如何使用Drop Table语句将表放入MySQL中? Mar 19, 2025 pm 03:52 PM

本文讨论了使用Drop Table语句在MySQL中放下表,并强调了预防措施和风险。它强调,没有备份,该动作是不可逆转的,详细介绍了恢复方法和潜在的生产环境危害。

如何在JSON列上创建索引? 如何在JSON列上创建索引? Mar 21, 2025 pm 12:13 PM

本文讨论了在PostgreSQL,MySQL和MongoDB等各个数据库中的JSON列上创建索引,以增强查询性能。它解释了索引特定的JSON路径的语法和好处,并列出了支持的数据库系统。

说明不同类型的MySQL索引(B树,哈希,全文,空间)。 说明不同类型的MySQL索引(B树,哈希,全文,空间)。 Apr 02, 2025 pm 07:05 PM

MySQL支持四种索引类型:B-Tree、Hash、Full-text和Spatial。1.B-Tree索引适用于等值查找、范围查询和排序。2.Hash索引适用于等值查找,但不支持范围查询和排序。3.Full-text索引用于全文搜索,适合处理大量文本数据。4.Spatial索引用于地理空间数据查询,适用于GIS应用。

See all articles