隔离级别
----------------
为了避免出现哪种并发现象的。
1 //read uncommitted ,读未提交
2 //read committed ,读已提交
4 //repeatable read ,可以重复读
8 //serializable ,串行化(悲观锁)
----------------
为了避免出现哪种并发现象的。
1 //read uncommitted ,读未提交
2 //read committed ,读已提交
4 //repeatable read ,可以重复读
8 //serializable ,串行化(悲观锁)
演示mysql事务隔离级别
------------------------
1.开启mysql客户端
mysql>
2.关闭自动提交
mysql>set autocommit 0 ;
3.每次操作数据,都要开启事务,提交事务。
------------------------
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 ;
----------------
[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
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 ;
----------------
[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
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;
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 ;
------------------
[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;
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 ;
------------------
[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;
5)mysql>commit;
6)mysql>start transaction ;
7)mysql>insert into users(name,age) values('tomas',13); -- 更新
8)mysql>commit;
ANSI SQL
---------------------
美国国家标准结构SQL组
select * from users for update ;
MySQL
----------------------
1.支持四种隔离级别。
2.默认隔离级别是可以重复读。
3.隔离级别是seriable,不支持并发写。
----------------------
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/big4";
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");
* 执行写,不提交
*/
@Test
public void testA() throws Exception{
//创建连接
String driverClass = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/big4";
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();
}
conn.commit();
conn.close();
}
/**
* 查询,查到别人没有提交的数据
*/
@Test
public void testB() throws Exception{
//创建连接
String driverClass = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/big4";
String username = "root";
String password = "root";
Class.forName(driverClass);
Connection conn = DriverManager.getConnection(url, username, password);
* 查询,查到别人没有提交的数据
*/
@Test
public void testB() throws Exception{
//创建连接
String driverClass = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/big4";
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();
/************************** 设置隔离级别 ***************************************/
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();
}
共享读锁
-------------
独占写锁
-------------
一个事务写操作,另一个塞住。
-------------
独占写锁
-------------
一个事务写操作,另一个塞住。
SQL
--------------------
//
insert into users(name,age,...) values('',12,..) ; -- insert
update users set name = 'xxx',age = xxx ,... where id = xxx ; -- update
delete from users where id = xxx -- delete
--------------------
//
insert into users(name,age,...) values('',12,..) ; -- insert
update users set name = 'xxx',age = xxx ,... where id = xxx ; -- update
delete from users where id = xxx -- delete
-- 投影查询 projection.
select id,name from users where ... order by limit xxx --select
select id,name from users where ... order by limit xxx --select
-- 查询时直接上独占写锁
select * from users for update ;
select * from users for update ;