找回密码
 立即注册

QQ登录

只需一步,快速开始

houys 悬赏达人认证 活字格认证
金牌服务用户   /  发表于:2024-1-15 11:23  /   查看:2711  /  回复:10
1金币
情况:服务端内查询订单表行数(id=参数),不存在则新增,存在则删除后再新增

可能会出现的问题:在这个服务端执行的过程中,另外的用户上传了相同的数据。
因为第一次的事务还没有关闭,即使第一次进行了新增数据,但是第二次查询行数还是为零
第二次就也会执行新增操作。就出现了重复行。
有可能也会出现死锁

最佳答案

查看完整内容

大佬您好,我看咱们群里发的图片,数据库使用的是SQL Server,在调用事务命令的时候,咱们的事务设置的隔离级别是不是“串行化(Serializable)” 所以使用了串行化,本身就是为了数据的一致性,会增加死锁的可能 咱们试试看,在事务命令的外部是否可以捕获到死锁的异常,因为看报错信息,若是死锁了之后,会将事务关闭掉,所以只需要在死锁了之后,重新执行一下命令,咱们使用异常捕获命令捕获一下死锁的异常,捕获到之后, ...

10 个回复

正序浏览
Joe.xu讲师达人认证 悬赏达人认证 活字格认证
超级版主   /  发表于:2024-7-15 18:07:56
11#
中文 发表于 2024-7-15 17:25
出现死锁可以用存储过程这个给KILL掉BEGIN  
    DECLARE done INT DEFAULT FALSE;  
    DECLARE thread ...

感谢分享
回复 使用道具 举报
中文
注册会员   /  发表于:2024-7-15 17:25:55
10#
出现死锁可以用存储过程这个给KILL掉BEGIN  
    DECLARE done INT DEFAULT FALSE;  
    DECLARE thread_id BIGINT;  
    DECLARE cur1 CURSOR FOR  
        SELECT ID  
        FROM information_schema.processlist  
        WHERE TIME > 120 AND COMMAND != 'Sleep' AND USER != 'system user';  
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;  
  
    OPEN cur1;  
  
    read_loop: LOOP  
        FETCH cur1 INTO thread_id;  
        IF done THEN  
            LEAVE read_loop;  
        END IF;  
  
        SET @s = CONCAT('KILL ', thread_id);  
        PREPARE stmt FROM @s;  
        EXECUTE stmt;  
        DEALLOCATE PREPARE stmt;  
    END LOOP;  
  
    CLOSE cur1;  
END
可以把这个存储过程放异常捕获

评分

参与人数 1金币 +5 收起 理由
Joe.xu + 5 很给力!

查看全部评分

回复 使用道具 举报
Grayson.Shang活字格认证 Wyn认证
超级版主   /  发表于:2024-1-16 17:37:03
9#
已和楼主联系,将事务的隔离级别设置成,“序列化”之后,重复添加数据的情况暂时没有再出现,死锁可能会偶尔出现


出现死锁之后,通过异常捕获命令,捕获异常,捕获到之后,重新再调用一下服务端命令就可以了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 使用道具 举报
houys悬赏达人认证 活字格认证
金牌服务用户   /  发表于:2024-1-16 14:47:55
8#
Grayson.Shang 发表于 2024-1-16 14:13
大佬您好,能具体的说一下咱们的业务场景吗,可能串行化隔离级别的事务操作,操作细节和咱们想要的有些区别 ...

情景就是   传递数据到服务端命令接收,判断这行数据是否存在于表中,存在则修改,不存在则新增
出现的问题是  包含这个事务的服务端有时候会很慢,不清楚慢的原因
就导致了 短时间内连续触发就会查到的都是不存在于表中,结果都进行了添加操作。数据就错误了
你描述的事务锁级别是符合的,但是我不清楚会不会对其他的需要使用到这张表的业务产生什么影响
比如其他事务一直排队导致操作很慢之类的
回复 使用道具 举报
Grayson.Shang活字格认证 Wyn认证
超级版主   /  发表于:2024-1-16 14:13:55
7#
大佬您好,能具体的说一下咱们的业务场景吗,可能串行化隔离级别的事务操作,操作细节和咱们想要的有些区别,所以想了解一下咱们具体的场景。

我现在大概可以理解您说的需求,咱们是希望每次执行事务之前对数据表增加“表级锁”的“排它锁”,这样在事务执行期间,其他的事务不能对数据表进行查询,更不能对数据表做其他修改数据的操作,等上一个事务执行完成了,再开始执行下一个事务,您看我对您的需求描述的有问题没。
回复 使用道具 举报
houys悬赏达人认证 活字格认证
金牌服务用户   /  发表于:2024-1-16 11:26:11
6#
JC壹玖玖伍 发表于 2024-1-15 16:12
“咱们试试看,在事务命令的外部是否可以捕获到死锁的异常,因为看报错信息,若是死锁了之后,会将事务关 ...

捕可以捕获到,但是主要是出现重复行的问题
回复 使用道具 举报
houys悬赏达人认证 活字格认证
金牌服务用户   /  发表于:2024-1-16 11:25:40
5#
Grayson.Shang 发表于 2024-1-15 15:59
大佬您好,我看咱们群里发的图片,数据库使用的是SQL Server,在调用事务命令的时候,咱们的事务设置的隔离 ...

最主要的问题是,如果没有死锁就会出现重复行,在一个事务未提交之前另一个事务进行查询新增操作。
就出现了重复行
回复 使用道具 举报
Grayson.Shang活字格认证 Wyn认证
超级版主   /  发表于:2024-1-15 16:27:36
4#
是的,服务端命令中的try-catch,就是异常捕获命令

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 使用道具 举报
JC壹玖玖伍活字格认证
金牌服务用户   /  发表于:2024-1-15 16:12:18
3#
Grayson.Shang 发表于 2024-1-15 15:59
大佬您好,我看咱们群里发的图片,数据库使用的是SQL Server,在调用事务命令的时候,咱们的事务设置的隔离 ...

“咱们试试看,在事务命令的外部是否可以捕获到死锁的异常,因为看报错信息,若是死锁了之后,会将事务关闭掉,所以只需要在死锁了之后,重新执行一下命令,咱们使用异常捕获命令捕获一下死锁的异常,捕获到之后,重新调用一下命令,看看是否可行”

使用try catch?
回复 使用道具 举报
最佳答案
最佳答案
Grayson.Shang活字格认证 Wyn认证
超级版主   /  发表于:2024-1-15 11:23:46
来自 2#
大佬您好,我看咱们群里发的图片,数据库使用的是SQL Server,在调用事务命令的时候,咱们的事务设置的隔离级别是不是“串行化(Serializable)”
通过完全串行化的方式执行事务,确保一个事务执行的效果等同于它们是顺序执行的。

解决了幻读的问题。

这种隔离级别可能带来较大的性能开销,并且增加了死锁的可能性。

所以使用了串行化,本身就是为了数据的一致性,会增加死锁的可能

咱们试试看,在事务命令的外部是否可以捕获到死锁的异常,因为看报错信息,若是死锁了之后,会将事务关闭掉,所以只需要在死锁了之后,重新执行一下命令,咱们使用异常捕获命令捕获一下死锁的异常,捕获到之后,重新调用一下命令,看看是否可行
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 立即注册
返回顶部