MySQL 多会话之间更新数据的小实例

1:创建一个实验表

mysql> use test;

mysql> CREATE TABLE t
    -> (id int(11) NOT NULL DEFAULT 0,
    -> num int(11) DEFAULT NULL,
    -> PRIMARY KEY(id))
    -> ENGINE=INNODB DEFAULT CHARSET=gbk;
Query OK, 0 rows affected (0.02 sec)

  

mysql> INSERT INTO t VALUES(1,100);

mysql> INSERT INTO t VALUES(2,200);
Session A Session B
mysql> BEGIN;  

mysql> SELECT * FROM t;
+----+------+
| id | num  |
+----+------+
|  1 |  100 |
|  2 |  200 |
+----+------+
2 rows in set (0.00 sec)

  

 
 

mysql> USE test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> INSERT INTO t VALUES(3,300);
Query OK, 1 row affected (0.01 sec)

  

mysql> SELECT * FROM t;
+----+------+
| id | num  |
+----+------+
|  1 |  100 |
|  2 |  200 |
+----+------+
2 rows in set (0.00 sec)

 

mysql> UPDATE t SET num=1000 WHERE id=3;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

上述查看并没有id=3的列,这里居然成功了!

 

mysql> SELECT * FROM t;
+----+------+
| id | num  |
+----+------+
|  1 |  100 |
|  2 |  200 |
|  3 | 1000 |
+----+------+
3 rows in set (0.00 sec)

  

 
从Session A整个过程看来,它试图更新一个不存在的记录(id=3),结果更新成功,并且之后这个记录可以访问。

为什么SessionA第二次检索仍然是2条记录呢?

    Innodb内部每个事务开始时,都会有一个事务id,同时事务对象中还有一个read_view变量,用于控制该事务可见的记录范围(MVCC)。

    对于每个访问到的记录行,会根据read_view的trx_id(事务id)与行记录的trx_id比较,判断记录是否逻辑上可见。

    Session B中插入的记录不可见,原因即为Session A先于session B,因此新插入的数据经过判断,不在可见范围内。对应的源码在row/row0sel.c [4040-4055].

  

Session A Session B

mysql> SELECT * FROM t;
+----+------+
| id | num  |
+----+------+
|  1 |  100 |
|  2 |  200 |
|  3 | 1000 |
+----+------+
3 rows in set (0.00 sec)

  

 
 

mysql> INSERT INTO t VALUES(4,400);
Query OK, 1 row affected (0.01 sec)

  

mysql> SELECT * FROM t;
+----+------+
| id | num  |
+----+------+
|  1 |  100 |
|  2 |  200 |
|  3 | 1000 |
+----+------+
3 rows in set (0.00 sec)

  

 

mysql> COMMIT;
Query OK, 0 rows affected (0.00 sec)

  

 

mysql> SELECT * FROM t;
+----+------+
| id | num  |
+----+------+
|  1 |  100 |
|  2 |  200 |
|  3 | 1000 |
|  4 |  400 |
+----+------+
4 rows in set (0.00 sec)

提交之后正常可见

 
时间: 2024-10-19 16:29:15

MySQL 多会话之间更新数据的小实例的相关文章

HDFS、Hive、MySQL、Sqoop之间的数据导入导出(强烈建议去看)

Hive总结(七)Hive四种数据导入方式 (强烈建议去看) Hive几种数据导出方式 https://www.iteblog.com/archives/955 (强烈建议去看) 把MySQL里的数据导入到HDFS 1.使用MySQL工具手工导入 把MySQL的导出数据导入到HDFS的最简单方法就是,使用命令行工具和MySQL语句. 为了导出整个数据表或整个数据库的内容,MySQL提供了mysqldump工具. 比如 SELECT  col1,col2 FORM TABLE INTO OUTFI

循序渐进VBA EXCEL数据操作小实例

1 向指定单元格区域内写入数据 Sub example1() Dim arr(1 To 3) arr(1) = Array("A", "B", "C", "D") arr(2) = Array("E", "F", "G", "H") arr(3) = Array("I", "J", "K"

MYSQL存储过程:批量更新数据

地区等级的信息储存在jsjh_district表. 要更新jsjh_goods_district表的district_level地区信息 DELIMITER $$ DROP PROCEDURE IF EXISTS update_district_level $$ CREATE PROCEDURE update_district_level() BEGIN DECLARE row_id INT;#定义变量ID DECLARE row_district_id INT;#定义变量地区ID DECLAR

[转]MYSQL 与 Oracle 之间的数据类型转换

原文地址:http://www.cnblogs.com/guyueyanzi/archive/2010/02/27/1674788.html Table 2-4 Default Data Type Mappings Used by Oracle SQL Developer MySQL Data Type Oracle Data Type BIGINT NUMBER(19, 0) BIT RAW BLOB BLOB, RAW CHAR CHAR DATE DATE DATETIME DATE DE

MYSQL存储过程:批量更新数据2(产品品牌)

执行语句 DELIMITER $$ DROP PROCEDURE IF EXISTS jsjh_goods_property_value_update$$ CREATE PROCEDURE jsjh_goods_property_value_update() BEGIN DECLARE row_base_brand varchar(50);#定义变量品牌 DECLARE row_title varchar(50);#定义tlete DECLARE row_value varchar(50);#定

mysql处理多表更新数据(1000万级别)

1. 表A(id,code,name,sex)表B(id,Aid,code,name,sex)B表中字段Aid为A表中的id.用一条语句将A表中code更新到B表中code中. UPDATE A SET A.code=B.code FROM B WHERE B.id=A.id; UPDATE A,B SET A.code=B.code WHERE B.id=A.id;

数据库中两张表之间的数据同步实现思路(增加、删除、更新)Mysql、sqlserver

分别创建增加.删除.更新的触发器(Trigger)来达到两张表之间数据同步的目的. 1:数据同步增加:如有两张表--A表和B表,创建触发器使当A表插入数据后B表也同步插入数据.其中B表插入数据的字段需要同A表中的字段相对应. CREATE TRIGGER 触发器名称 ON A表 AFTER INSERT AS BEGIN INSERT INTO B表(B表字段1,B表字段2,B表字段3) SELECT A表字段1,A表字段2,A表字段3 FROM INSERTED END 2.数据同步删除:如有

在MySQL和分布式TiDB之间迁移数据

在MySQL和分布式TiDB之间迁移数据,这里用到mydumper工具. 迁移分为2步: 第1步:dump到本地,需要保证本地有足够的磁盘空间 import os import sys import datetime import subprocess src_db1 = 'test1' src_table1 = 'table1' dump_time1 = datetime.datetime.now().strftime("%Y%m%d_%H%M") file_path1 = '/ho

动态加载页面数据的小工具 javascript + jQuery (持续更新)

使用该控件,可以根据url,参数,加载html记录模板(包含json参数对应,以及具体记录位置Index根据参数描述加载对应的属性,并可以根据简单的判断分支加载对应html或者控件)至列表容器内(JQuery选择器字符串)注: 该控件在使用前需引入JQuery框架支持,使用该控件,可极大的减少Ajax列表数据动态加载开发工作的实际工作量. 使用方式: 首先,添加控件引用,并加入Jquery支持 <script src="js/jquery.js"></script&g