在数据库上实现类似铁路售票锁票功能

要实现铁路售票那样的效果,如果有票查询到就锁定票,如果客人不购买再将票放回票池,这样可以保证前来买票的旅客只要查询到有票就一定能够买到票。我们可以通过给数据库增加一个锁定的标志字段来完成,但这里我们可以试试数据库本身的功能能否实现这个需求。

首先想到的是事务,如果对一个表开始更新以后,那么另外一个会话查询这个标的时候,会等待前一个更新数据的会话释放事务,这是因为普通的SQL读操作内部其实使用了“已提交读”的事务隔离级别,可以保证数据的准确性。但是这不符合我们的需求,我们希望另外一个查询会话能够很快的进行查询,同时过滤掉被“锁票”的数据。

在更新会话中,执行下面的查询:

begin tran
update Users  set Name=‘aaa‘  where UID= 610062

新开一个查询窗口,此时会新开一个连接会话,执行一个查询:

 select * from LocalDB.dbo.Users 

此时发现查询会话会一直等待,直到更新会话提交事务或者回滚事务:

begin tran
update Users  set Name=‘aaa‘  where UID= 610062

rollback

再次执行上面的更新会话,但不提交事务,此时,我们的查询会话可以使用 nolock,不会让查询等待。

  select * from LocalDB.dbo.Users(nolock) 

但是这样把前面更新的数据也查询出来了,不过是旧数据,不符合我们的需求。此时可以使用 行锁加过滤锁:

 select * from LocalDB.dbo.Users  with (rowlock,xlock,readpast)

成功实现需求!

另外,网友 听风吹雨 也提供了另外的思路,详细看下面的查询代码:

use master
go

---创建测试数据库(快照)
create database SNAPSHOT_Test
go

---激活数据行版本控制
alter database SNAPSHOT_Test  set Allow_SNAPSHOT_isolation on
go

use SNAPSHOT_Test
go

--1.创建测试表
create table tbReadLevel
(ID INT,
name nvarchar(20)
)

--2新增记录
insert tbReadLevel
select 1,‘测试‘
union
select 2,‘快照测试‘
go

select ID,name as "修改前数据"
from tbReadLevel
go

--3开启事务
begin tran
update tbReadLevel
set name=‘Jack_upd_快照‘
where ID=1

--5打开另一条连接
set Transaction isolation level SNAPSHOT
select * from tbReadLevel

时间: 2024-10-22 11:49:10

在数据库上实现类似铁路售票锁票功能的相关文章

在 Oracle 数据库上使用 Visual Studio 2005 或 2008 构建 .NET 应用程序 了解构建使用 Oracle 数据库的 .NET 应用程序所涉及到的基本但不可或缺的过程。

随着 Microsoft 的 .NET Framework 的日益流行,许多开发人员迫切想了解关于将 .NET 应用程序与 Oracle 集成的最佳方法的信息 - 不仅在基本连通性方面,还包括与使用 Visual Studio 2005 或 2008 进行有效应用程序开发的关系. 在本文中,我将说明构建使用 Oracle 数据库的 .NET 应用程序所涉及到的基本但不可或缺的过程,包括: 如何添加工程引用,以在您的 .NET 工程中支持 Oracle 类 如何创建 Oracle 数据库连接字符串

MySQL数据库InnoDB存储引擎中的锁机制--转载

原文地址:http://www.uml.org.cn/sjjm/201205302.asp 00 – 基本概念 当并发事务同时访问一个资源的时候,有可能导致数据不一致.因此需要一种致机制来将访问顺序化. 锁就是其中的一种机制.我们用商场的试衣间来做一个比喻.试衣间供许多消费者使用.因此可能有多个消费者同时要试衣服.为了避免冲突,试衣间的门上装了锁.试衣服的人在里边锁住,其他人就不能从外边打开了.只有里边的人开门出来,外边的人才能进去. - 锁的基本类型 数据库上的操作可以归纳为两中,读和写.多个

MySQL数据库InnoDB存储引擎中的锁机制

MySQL数据库InnoDB存储引擎中的锁机制    http://www.uml.org.cn/sjjm/201205302.asp   00 – 基本概念 当并发事务同时访问一个资源的时候,有可能导致数据不一致.因此需要一种致机制来将访问顺序化. 锁就是其中的一种机制.我们用商场的试衣间来做一个比喻.试衣间供许多消费者使用.因此可能有多个消费者同时要试衣服.为了避免冲突,试衣间的门上装了锁.试衣服的人在里边锁住,其他人就不能从外边打开了.只有里边的人开门出来,外边的人才能进去. - 锁的基本

12306铁路售票系统核心开源中间件Geode介绍

Geode是一个提供实时且高一致性的分布式数据管理平台,典型案例是中国铁路12306售票系统使用Geode管理10个集群节点,在内存中管理2T的热点数据和10个高可用弹性规模的后备节点. Geode通过内存池 CPU 网络资源和可选本地磁盘跨多个进程来管理对象和行为,它使用动态复制和数据分区技术实现高可用性以及提高性能,保证高扩展性和容错性,除了是一个分布式数据容器,Geode还是一个内存in-memory内存数据管理系统提供可靠的异步事件通知和保证信息传递. Geode作为一个极其成熟和强大的

数据库的数据类型、索引、锁、事务和视图

数据库的数据类型.索引.锁.事务和视图 数据的类型 1)数据类型: 数据长什么样? 数据需要多少空间来存放? 系统内置数据类型和用户定义数据类型 2)MySql 支持多种列类型: 数值类型 日期/时间类型 字符串(字符) 类型 3)选择正确的数据类型对于获得高性能至关重要,三大原则: 更小的通常更好,尽量使用可正确存储数据的最小数据类型 简单就好,简单数据类型的操作通常需要更少的CPU 周期 尽量避免NULL,包含为NULL的列,对MySQL更难优化 4)整型 tinyint(m) 1节个字节,

多线程- 铁路售票学习

/** * 需求:铁路售票,一共100张,通过四个窗口卖完. */ public static void main(String[] args) { new Ticket().start(); new Ticket().start(); new Ticket().start(); new Ticket().start(); } } class Ticket extends Thread { private static int ticket = 100; //private static Obj

PL/SQL跑在Oracle 64位数据库上初始化错误

安装完Oracle(64位).PL/SQL后运行PL/SQL出现如下的错误: 网上查资料说,我的PL/SQL与ORACLE不兼容,即PL/SQL不支持64位的ORACLE,因此得下一个32位的ORCALE客户端并配置相应的参数: 解决步骤小记: 一.下载ORACLE 32位客户端 下载地址:http://www.onlinedown.net/soft/102902.htm(Oracle 10g客户端精简绿色版) 二.解压到ORACLE 安装目录下一个叫product的目录下,并重命名一下(命名不

Mysql数据库上修改日期-->造数据

这次要给客户安装测试ineedle设备,但是安装后不会立刻有数据显示,不能够全面的展示给用户web界面的一些信息.此时需要有一个公网服务器能够展示一下ineedle统计数据,但是公司58设备上没有流量了,近期的数据没有更新了,所以准备将数据库中实际数据抽出几天的更改一下日期,使其展示ineedle的web界面上.最新的七天数据是2015.07.27--2015.08.02这7天的数据,正好一个星期.计划是将2015.07.27-2015.08.02修改为2015.10.19-2015.10.25

数据库上钻、下钻、切片

转自:http://zhidao.baidu.com/link?url=EXZLJdG23DbUvFDaZAG0qOd-_QMIbkdYqUzpmV3VeOGHBoP3oGf2lGwIrld8ePI28Zd2FTb5cv1vuKF19G60nK 上钻:从当前数据往上回归到上一层数据.例如:(某数据的分类下面分为品名)从品名列表收拢到分类列表.下钻:从当前数据往下展开下一层数据.例如:(某数据的分类下面分为品名)从分类列表展开到品名列表.上钻.下钻统称钻取.切片:展现同一层面的数据.如上述的产品.