数据库并行访问控制之互斥显示

Netkiller MySQL 手札

MySQL MariaDB...

Mr. Neo Chan, 陈景峰(BG7NYT)

中国广东省深圳市龙华新区民治街道溪山美地
518131
+86 13113668890
+86 755 29812080
<netkiller@msn.com>

文档始创于2010-11-18

版权 2011, 2012, 2013 Netkiller(Neo Chan). All rights reserved.

版权声明

转载请与作者联系,转载时请务必标明文章原始出处和作者信息及本声明。

文档出处:
http://netkiller.github.io
http://netkiller.sourceforge.net

 

$Date: 2013-04-10 15:03:49 +0800 (Wed, 10 Apr 2013) $

我的系列文档

 

Netkiller Architect 手札 Netkiller Developer 手札 Netkiller PHP 手札 Netkiller Python 手札 Netkiller Testing 手札 Netkiller Cryptography 手札
Netkiller Linux 手札 Netkiller CentOS 手札 Netkiller FreeBSD 手札 Netkiller Security 手札 Netkiller Version 手札 Netkiller Web 手札
Netkiller Monitoring 手札 Netkiller Storage 手札 Netkiller Mail 手札 Netkiller Shell 手札 Netkiller Network 手札 Netkiller Database 手札
Netkiller PostgreSQL 手札 Netkiller MySQL 手札 Netkiller NoSQL 手札 Netkiller LDAP 手札 Netkiller Cisco IOS 手札 Netkiller H3C 手札
Netkiller Multimedia 手札 Netkiller Docbook 手札 Netkiller 开源软件 手札  
 

 

 

 

第 9 章 数据库并行访问控制

 

目录

9.1. 防止并行显示

这里主要讲述有关开发中遇到的数据库并行问题

9.1. 防止并行显示

 

背景

我们有一个order订单表,工作流如下

创建订单 -> 订单分配 -> 订单审核 -> 批准 -> 发货 ... 等等			

有多个岗位,每个岗位上有多个工作人员。需要实现相同岗位上的工作人员看到的订单不能重复,防止多人同时操作一个订单。

id | user | sn    | status
-----------------------------------
1  | neo  | x001  | new
2  | jam  | x002  | new
3  | sam  | x003  | new
4  | tom  | x004  | new
5  | ann  | x005  | new
6  | leo  | x006  | new
7  | ant  | x007  | new
8  | cat  | x008  | new
		

正常情况只要是多人一起打开订单页面就会显示上面的订单,并且每个人显示的内容都相同。

CREATE TABLE `orders` (
	`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
	`name` VARCHAR(50) NOT NULL,
	`sn` INT(10) UNSIGNED ZEROFILL NOT NULL,
	`status` ENUM('New','Pending','Processing','Success','Failure') NOT NULL DEFAULT 'New',
	PRIMARY KEY (`id`),
	UNIQUE INDEX `sn` (`sn`)
)
COMMENT='订货单'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
		
INSERT INTO `orders` (`id`, `name`, `sn`, `status`) VALUES
	(1, 'neo', 0000000001, 'New'),
	(2, 'jam', 0000000002, 'New'),
	(3, 'sam', 0000000003, 'New'),
	(4, 'tom', 0000000004, 'New'),
	(5, 'ann', 0000000005, 'New'),
	(6, 'leo', 0000000006, 'New'),
	(7, 'ant', 0000000007, 'New'),
	(8, 'cat', 0000000008, 'New');
		

表 9.1. 工作流模拟

操作 订单审核员 A 订单审核员 B

显示未处理订单,这里模拟两个人同时点开页面的情景
begin;
select id from orders where status='New' limit 5 for update;
update orders set status='Pending' where status='New' and id in (1,2,3,4,5);
select * from orders where status='Pending' and id in (1,2,3,4,5) order by id asc limit 5;
commit;
							

首先查询出数据库中的前五条记录,然后更新为Pending状态,防止他人抢占订单。

begin;
select id from orders where status='New' limit 5 for update;
update orders set status='Pending' where status='New' and id in (6,7,8);
select * from orders where status='Pending' and id in (6,7,8) order by id asc limit 5;
commit;
							

select的时候会被行级所挂起,直到被commit后才能查询出新数据,这是显示的数据是剩下的后5条

处理订单,模拟两个人点击审批通过按钮是的情景
begin;
select * from orders where status='Pending' and id='1' for update;
update orders set status='Processing' where status='Pending' and id=1;
commit;
							

更新状态Pending到Processing

begin;
select * from orders where status='Pending' and id='6' for update;
update orders set status='Processing' where status='Pending' and id=6;
commit;
							

更新状态Pending到Processing

处理成功与失败的情况
begin;
select * from orders where status='Processing' and id='1' for update;
update orders set status='Success' where status='Processing' and id=1;
commit;
							
begin;
select * from orders where status='Processing' and id='6' for update;
update orders set status='Failure' where status='Processing' and id=6;
commit;
							
处理Pending状态的订单,可能产生冲突,不用担心有行锁,防止重复处理。
begin;
select * from orders where status='Processing' and id='5' for update;
update orders set status='Failure' where status='Processing' and id=5;
commit;
							
begin;
select * from orders where status='Processing' and id='5' for update;
update orders set status='Failure' where status='Processing' and id=5;
commit;
							

有一种情况,用户查看了列表并未及时处理订单,就会有很多Pending状态的订单,这是需要有人处理这些订单,但查询Pending时,可能同一时刻有人在审批订单,我们通过排他锁避免重复处理。

时间: 2024-10-21 20:25:22

数据库并行访问控制之互斥显示的相关文章

第 7 章 数据库并行访问控制

这里主要讲述有关开发中遇到的数据库并行问题 7.1. 防止并行显示 背景 我们有一个order订单表,工作流如下 创建订单 -> 订单分配 -> 订单审核 -> 批准 -> 发货 ... 等等 有多个岗位,每个岗位上有多个工作人员.需要实现相同岗位上的工作人员看到的订单不能重复,防止多人同时操作一个订单. id | user | sn | status ----------------------------------- 1 | neo | x001 | new 2 | jam

ASP,安全写入数据库操作,正常读出并显示在不同的场合

安全|数据|数据库|显示|安全   比如说有styledesc这个字段,数据要求的是50位,char形,可不可以只限制他50位,其它的不限制,输入什么字符都可以的.只要是char形,只要数据库允许就行 这样,安全写入数据库操作,正常读出并显示在不同的场合,应用. 应该是怎样做呢? 下面是我总结的几点.非常有可能不对,请指正.如果对用户的输入是可以任意字符,(除了某字段特定的输入限制条件,如输入长度,输入类型==).就是输入尽可能不作限制. 对一字符串str,他输出的方向有以下几种:1.输出至HT

JSP数据库操作例程 - 数据分页显示

js|分页|数据|数据库|显示 <%-- 作者:何志强[hhzqq@21cn.com] 日期:2000-08-03 版本:1.0 功能:JSP数据库操作例程 - 数据分页显示 - JDBC 2.0 - Oracle --%> <%@ page contentType="text/html;charset=8859_1" %> <% //变量声明 java.sql.Connection sqlCon; //数据库连接对象 java.sql.Statement

JSP数据库操作例程 - 数据分页显示 - JDBC 2.0 - Oracle

js|oracle|分页|数据|数据库|显示 <%@ page contentType="text/html;charset=8859_1" %> <% //变量声明 java.sql.Connection sqlCon; //数据库连接对象 java.sql.Statement sqlStmt; //SQL语句对象 java.sql.ResultSet sqlRst; //结果集对象 java.lang.String strCon; //数据库连接字符串 java.

让我来教你吧,看这个例子:JSP数据库操作例程 - 数据分页显示 - JDBC 2.0 - Oracle

js|oracle|分页|数据|数据库|显示 <%--作者:何志强[hhzqq@21cn.com]日期:2000-08-03版本:1.0功能:JSP数据库操作例程 - 数据分页显示 - JDBC 2.0 - Oracle--%> <%@ page contentType="text/html;charset=8859_1" %> <%//变量声明java.sql.Connection sqlCon; //数据库连接对象java.sql.Statement

JSP数据库操作例程数据分页显示

js|分页|数据|数据库|显示 <%@ page contentType="text/html;charset=8859_1" %> <% //变量声明 java.sql.Connection sqlCon; //数据库连接对象 java.sql.Statement sqlStmt; //SQL语句对象 java.sql.ResultSet sqlRst; //结果集对象 java.lang.String strCon; //数据库连接字符串 java.lang.St

数据库记录集的分列显示

记录集|数据|数据库|显示 数据库记录集的分列显示 /**@作者 : 慈勤强@Email : cqq1978@Gmail.com*/ 在用asp.php或者其他语言从数据库中提取记录显示的时候,一般我们都是一行一行 的显示,一条记录一行,就像下面的样子: 姓名 性别 年龄 籍贯慈勤强 男 26 山东省荣成市李冉 男 26 北京方庄 可是有时候,我们也需要分列显示,就是每行显示多条记录,特别是一些类别显示的,比如: 化工行业 纺织行业 服装鞋帽 电子信息 制造业 农林 水产 共三列,每行显示3条信

mysql-php从数据库中读取某个表中的数据并在页面中一条条列出来,代码如下,数据库里有信息,显示不出来

问题描述 php从数据库中读取某个表中的数据并在页面中一条条列出来,代码如下,数据库里有信息,显示不出来 <?php include(""connectDB.php""); @$query=mysql_query($conSELECT * from xx""); @$result=mysql_fetch_array(@$query); if($result==true){ ?> <table width=""

如何从sqlite数据库中获取数据并显示在listview中?

问题描述 如何从sqlite数据库中获取数据并显示在listview中? 在登录页面后,我想在listview中把Apple显示成A,Boy显示成B等等,直到F.但是在程序中当我完全登录后,只有登录表成功创建,主菜单还是没有创建. 我想在test database中创建主菜单,然后我想从主菜单表(mainmenu table)中获取数据再显示在listview中. 我使用了下面的代码: if(username.length()>0&&password.length()>0) {