`
zhengdl126
  • 浏览: 2540335 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类

数据库中的隔离级别和锁机制

 
阅读更多

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 name='zhangsan11' 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修改后的数据)

分享到:
评论

相关推荐

    06-VIP-深入理解Mysql事务隔离级别与锁机制.pdf

    深入理解Mysql事务隔离级别与锁机制 Mysql事务隔离级别与锁机制是数据库...在实际应用中,需要根据不同的应用场景选择合适的事务隔离级别和锁机制,来解决多事务并发问题,提高数据库的并发访问性能和数据的一致性。

    深入理解Mysql事务隔离级别与锁机制.pdf

    "深入理解Mysql事务隔离级别与锁机制" 事务隔离级别是数据库系统中的一种机制,...在实际应用中,选择合适的事务隔离级别和锁机制非常重要,需要根据具体的应用场景来选择合适的机制,以确保数据的一致性和可靠性。

    详解Mysql事务隔离级别与锁机制.doc

    详解Mysql事务隔离级别与锁机制 ...Mysql事务隔离级别与锁机制是数据库系统中的一种机制,用于解决多事务并发问题和数据并发访问的一致性问题。了解这些机制对数据库系统的设计和实现有重要的参考价值。

    数据库的隔离级别介绍

    总的来说,数据库隔离级别的选择是一个权衡过程,需要在数据一致性、并发性和性能之间找到合适的平衡点。在设计数据库系统和应用程序时,理解这些隔离级别及其可能产生的效果至关重要,以便做出最佳决策。

    数据库中锁机制的学习

    数据库中的锁机制是确保数据一致性、并发控制和事务隔离的重要机制。在多用户环境中,当多个用户同时访问和操作同一份数据时,可能会引发数据冲突和不一致。为了解决这些问题,数据库系统引入了锁来协调并发操作。...

    深入分析MSSQL数据库中事务隔离级别和锁机制

    在MSSQL数据库中,事务隔离级别和锁机制是确保数据一致性、并发性和避免数据冲突的关键要素。事务隔离级别决定了事务在执行时与其他事务的交互方式,而锁机制则是实现这些隔离级别的具体手段。 首先,让我们理解...

    深入理解Mysql事务隔离级别与锁机制.zip

    本知识点将深入探讨MySQL中的事务隔离级别和锁机制,这是确保数据一致性和并发控制的关键概念。 首先,让我们了解什么是事务。在数据库中,事务是一系列操作的集合,这些操作被视为一个逻辑工作单元,要么全部执行...

    MSSQL与Oracle数据库事务隔离级别与锁机制对比

    理解事务隔离级别和锁机制对于优化数据库性能和保证数据一致性至关重要。根据具体应用场景选择合适的隔离级别,并合理利用锁机制,可以在保障数据安全的同时,提高系统的并发处理能力。在MSSQL和Oracle这样的大型...

    数据库_事务隔离级别与锁.docx

    ### 数据库事务隔离级别与锁 #### 一、事务的基本特征 事务是数据库管理系统的核心概念之一,用于确保数据的一致性和正确性。事务通常具备以下四个特性,即ACID特性: 1. **原子性(Atomicity)**:事务被视为一...

    数据库快照隔离级别(Snapshot Isolation)技术详解与应用

    快照隔离级别是一种强大的事务隔离机制,它通过提供一致性的数据库视图和减少锁的使用,提高了数据库的并发性能和减少了死锁的可能性。了解和掌握快照隔离级别的工作原理和配置方法,对于数据库管理员和开发人员来说...

    数据库事务隔离级别.docx

    事务隔离级别是数据库管理系统中用于控制事务并发的关键机制之一。选择合适的隔离级别不仅能够保证数据的一致性和准确性,还能在一定程度上平衡系统的并发性能。在实际应用中,应根据业务需求和并发特性综合考虑选择...

    MS SQL Server数据库事务锁机制分析

    事务隔离级别也是SQL Server中控制锁行为的关键因素,不同的隔离级别(如读未提交、读已提交、可重复读和串行化)会影响事务看到的数据版本和锁的使用。例如,较高的隔离级别可能会使用更多的锁来防止脏读、不可重复...

    oracle 数据库隔离级别学习

    Oracle 数据库隔离级别是数据库事务处理中的核心概念,它决定了事务在并发环境下如何访问和处理数据,以确保数据的一致性和完整性。隔离级别主要解决的是并发操作中的脏读、不可重复读和幻读问题。 脏读(Dirty ...

    sybase数据库查被锁的表.doc

    Sybase 数据库锁机制和锁表查询 Sybase 数据库锁机制是指...Sybase 数据库锁机制和锁表查询是数据库管理系统中非常重要的组件,可以帮助数据库管理员了解和优化数据库中的锁情况,从而提高数据库的性能和可靠性。

    mysql数据库事务隔离级别借鉴.pdf

    数据库事务是确保数据库操作一致性的重要机制,特别是在并发环境中。事务隔离级别是数据库系统用来解决并发控制...在并发操作频繁的环境中,需要权衡一致性和性能,选择最适合的隔离级别来保证数据的完整性和一致性。

    GBase 8s隔离级别

    隔离级别是数据库系统解决并发控制的重要机制,它定义了事务在执行过程中如何与其他事务交互,防止出现并发操作时可能引发的问题,如脏读、幻读和不可重复读。 1. 脏读 (Dirty Read) 脏读在GBase 8s中对应于"读未...

    数据库事务隔离级别的深入解析与代码实现

    数据库事务隔离级别是确保数据一致性和完整性的重要机制。通过合理设置事务隔离级别,可以在保证数据一致性的同时,优化数据库的并发性能。开发者需要根据具体的应用场景和业务需求,选择最合适的事务隔离级别,并在...

    mysql数据库事务隔离级别[参照].pdf

    数据库事务是确保数据库操作一致性的重要机制,特别是在并发环境中。事务隔离级别是数据库系统用来解决并发...因此,在设计和优化数据库时,理解这些隔离级别和其背后的锁机制至关重要,以确保并发场景下的数据一致性。

Global site tag (gtag.js) - Google Analytics