Mysql 事务


事务的并发执行,容易出现的几个现象

    1.脏读
        读未提交,一个事务读取了另外一个事务改写还没有提交的数据,如果另外一个
        事务在稍后的时候回滚。

    2.不可重复读
        一个事务进行相同条件查询连续的两次或者两次以上,每次结果都不同。
        有其他事务做了update操作。

    3.幻读
        和(2)很像,其他事务做了insert操作.


隔离级别
    为了避免出现哪种并发现象的。
    1        //read uncommitted    ,读未提交
    2        //read committed    ,读已提交
    4        //repeatable read    ,可以重复读
    8        //serializable        ,串行化(悲观锁)

演示mysql事务隔离级别

    1.开启mysql客户端
        mysql>
    2.关闭自动提交
        mysql>set autocommit=0 ;
    3.每次操作数据,都要开启事务,提交事务。

脏读现象

    [A]
        1)mysql>start transaction ;                                -- 开始事务
        2)msyql>update users set age = age + 1 where id = 1 ;    -- 更新数据,没有提交
        6)mysql>rollback ;                                        -- 回滚
        7)mysql>select * from users ;

    [B]
        3)mysql>set session transaction isolation level read uncommitted ;    -- 读未提交
        4)msyql>start transaction ;        -- 开始事务
        5)mysql>select * from users ;    -- 13

避免脏读

    [A]
        1)mysql>start transaction ;                                -- 开始事务
        2)msyql>update users set age = age + 1 where id = 1 ;    -- 更新数据,没有提交
        6)mysql>rollback ;                                        -- 回滚
        7)mysql>select * from users ;

    [B]
        3)mysql>set session transaction isolation level read committed ;    -- 读已提交
        4)msyql>start transaction ;        -- 开始事务
        5)mysql>select * from users ;    -- 13


测试不可重复读(隔离级别设置为读已提交不能避免不可重复读。)

    [A]
        1)mysql>commit ;
        2)mysql>set session transaction isolation level read committed ;    -- 读已提交
        3)mysql>start transaction ;                                            -- 开始事务
        4)mysql>select * from users    ;                                        -- 查询
        9)mysql>select * from users    ;

    [B]
        5)mysql>commit;
        6)mysql>start transaction ;    
        7)mysql>update users set age = 15 where id = 1 ;                    -- 更新
        8)mysql>commit;

测试避免不可重复读(隔离级别设置为读已提交不能避免不可重复读。)

    [A]
        1)mysql>commit ;
        2)mysql>set session transaction isolation level repeatable read ;    -- 可以重复读
        3)mysql>start transaction ;                                            -- 开始事务
        4)mysql>select * from users    ;                                        -- 查询
        9)mysql>select * from users    ;

    [B]
        5)mysql>commit;
        6)mysql>start transaction ;    
        7)mysql>update users set age = 15 where id = 1 ;                    -- 更新
        8)mysql>commit;

测试幻读(隔离级别设置为repeatable)

    [A]
        1)mysql>commit ;
        2)mysql>set session transaction isolation level serializable;        -- 串行化
        3)mysql>start transaction ;                                            -- 开始事务
        4)mysql>select * from users    ;                                        -- 查询
        9)mysql>select * from users    ;

    [B]
        5)mysql>commit;
        6)mysql>start transaction ;    
        7)mysql>insert into users(name,age) values('tomas',13);                -- 更新
        8)mysql>commit;


MySQL

    1.支持四种隔离级别。
    2.默认隔离级别是可以重复读。
    3.隔离级别是seriable,不支持并发写。

隔离级别越高,安全性越好,但是性能越差

串行化级别是悲观锁,不支持并发


表级锁

    LOCK TABLE t WRITE;    -- 加锁(表级锁,read)
    
    UNLOCK TABLES ;        -- 解除自己所有的所有表级锁
    


编程实现脏读现象

package com.it18zhang.jdbcdemo.test;
	import org.junit.Test;
	import java.sql.*;
	/**
	 * 测试隔离级别
	 */
	public class TestIsolationLevel {

		/**
		 * 执行写,不提交
		 */
		@Test
		public void testA() throws  Exception{
			//创建连接
			String driverClass = "com.mysql.jdbc.Driver";
			String url = "jdbc:mysql://localhost:3306/test";
			String username = "root";
			String password = "root";
			Class.forName(driverClass);
			Connection conn = DriverManager.getConnection(url, username, password);
			conn.setAutoCommit(false);
			Statement st = conn.createStatement();
			st.execute("update users set age = 80 where id = 1");

			System.out.println("===============");
			conn.commit();
			conn.close();
		}

		/**
		 * 查询,查到别人没有提交的数据
		 */
		@Test
		public void testB() throws  Exception{
			//创建连接
			String driverClass = "com.mysql.jdbc.Driver";
			String url = "jdbc:mysql://localhost:3306/test";
			String username = "root";
			String password = "root";
			Class.forName(driverClass);
			Connection conn = DriverManager.getConnection(url, username, password);

			//设置隔离级别读未提交==>导致脏读
			/************************** 设置隔离级别 ***************************************/
			conn.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
			conn.setAutoCommit(false);
			Statement st = conn.createStatement();


			ResultSet rs = st.executeQuery("select age from users where id = 1");
			rs.next();
			int age = rs.getInt(1) ;
			System.out.println(age);
			System.out.println("===============");
			conn.commit();
			conn.close();
		}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值