事务的隔离级别与高并发

yangguosheng 2016-09-30 03:33:29
系统业务就是查询出一条数据,根据这条数据计算,再update这条数据。

假如业务严格要求这个过程在一条记录上同时只能有一个线程在执行。比如票据的验证使用,先要查出是否可以使用,如果可以使用则执行验证操作。这个过程在同一张票据上只允许一个线程在执行。如果两个线程同时执行验票逻辑,A先查数据可以验证,B后查询也可以验证,A执行验证,B再执行验证。就会发生重复验证的我问题。

那么我将这个过程放到一个事务当中,并且设置隔离级别。我发现没有合适的隔离级别。REPEATABLE READ不能阻止其他线程读取当前记录。我需要其他线程不能执行查询操作,等其他事务提交以后再查询。

请问我这种那个情况我该怎么处理。另外事务过程当中有大量的业务逻辑,如果处理业务也需要一定的时间,如何解决高并发的问题。
...全文
1138 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaoxiangqing 2016-10-22
  • 打赏
  • 举报
回复
1楼的回复得太好了。
巴拉莱卡 2016-10-22
  • 打赏
  • 举报
回复
避免读脏数据的问题可以加锁。 不过你这块更适合在改写阶段用只读锁,即查询和改写分开,避免加锁时间过长。
巨巨巨 2016-10-14
  • 打赏
  • 举报
回复
使用一个记录表用来记录当前正在被查看验证的票据号,每次准备去查看验证某一票据之前,先去这个记录表里查找是否已经登记了记录,已登记的话就不能继续进行查找验证;没登记的话,就首先插入一条记录登记此票据,然后执行操作,验证完后去记录表删除这条登记记录。 这做法可以控制同时只能一个人去验证
想到才能做到 2016-10-13
  • 打赏
  • 举报
回复
查询时上锁,验证后解锁。
中国风 2016-10-11
  • 打赏
  • 举报
回复
在联机帮助,查找 这个值可直接改为数字或时间显示
yangguosheng 2016-10-11
  • 打赏
  • 举报
回复
引用 2 楼 roy_88 的回复:
并发建议用时间戳去处理 在表新一个列为timestamp,在获取验证时判断是否在开始事务到 结束事务间有没有改变过
用时间戳判断为什么要比加锁更高效呢?而且判断时间戳还需要多查询一次。
中国风 2016-09-30
  • 打赏
  • 举报
回复
并发建议用时间戳去处理 在表新一个列为timestamp,在获取验证时判断是否在开始事务到 结束事务间有没有改变过
中国风 2016-09-30
  • 打赏
  • 举报
回复
e.g.
USE tempdb

GO

 

CREATE TABLE dbo.tb(

id int identity(1, 1), 

name nvarchar(128))

 

INSERT  tb
        ( name
        )
        SELECT TOP 100
                name
        FROM    syscolumns;


--   模拟第1个用户

-- 查询窗口发出下面的查询语句
BEGIN TRAN
-- 事务不提交或者回滚, 以保持锁不释放
SET ROWCOUNT 20

SELECT * 

FROM tb WITH(UPDLOCK, READPAST)



-- 模拟第2个用户

-- UPDLOCK 让锁保留到事务结束, READPAST 跳过已经锁定的数据

-- 查询窗口发出下面的查询语句

BEGIN TRAN
-- 事务不提交或者回滚, 以保持锁不释放

SET ROWCOUNT 20

SELECT * 

FROM tb WITH(UPDLOCK, READPAST)

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧