关于事务与并发

今天看到一个技术群里面聊到事务与并发的关系,发现好多开发者的理解不一样,想把自己再工作中遇到的例子在这里呈现出来,以告诉大家自己所理解的事务与并发,先简单说下流程吧!

我们公司的A,B系统通信使用的是ActiveMQ,主要是订单状态的通信,之前遇到的一个问题是A系统通过一个事务修改了订单的状态要通过ActiveMQ通知B系统,B系统收到通知并处理后会再通过ActiveMQ告知A系统通知完毕,再这个过程中订单在A系统里面有一个字段来标示订单状态,简要的步骤就是:

  • A系统处理一个事务后修改订单状态
  • 通过ActiveMQ通知B系统,B系统收到通知后再通过ActiveMQ告知A系统
  • A系统再启动一个事务修改订单状态
  • 假设订单状态正常由第一步骤到第三步骤的状态变化为pending---finish

我们遇到的问题是什么呢?经过上述步骤之后发现A系统里面的有些订单状态还是处于pending,而根据日志可以看到A系统是收到了B系统里面的消息的,并且可以确认A系统里面的两个事务都是有执行的。

也就是说,在A系统里面,有些订单的第二个事务是执行在第一个事务之后的。

后来查看了一下代码,发现我们的代码实现实际上是这样的,上面过程的第二步骤发生在第一步骤的事务未执行完就通知了B系统,这就可以解释上面的现象了,由于订单和网络传输的差异造成A系统事务执行顺序的差异。

解决方法:将代码里面通知B系统的模块移到A系统里面的第一个事务执行完毕之后。

这里面就有事务跟并发的关系了,在A系统里面按照正常流程会启动两个顺序不同的事务来修改订单的状态,而由于代码编写的问题造成A系统里面的第一个事务未执行完毕就执行了第二个事务。由这个问题我们可以引申出很多的事务并发问题,比方说在设计一个系统的时候,当涉及到某些表里面的状态字段时,我们更多需要的是一个流程化的设计,而不是状态是随便在哪个环节就可以改变的,要是真有那种需求的话,就是使用数据库的锁了,不过一般是不会这么设计的,如果要我选择的话,我觉得流程化会更加好一点。

时间: 2024-12-19 08:09:52

关于事务与并发的相关文章

数据库中的事务和并发问题探讨

数据库中的事务和并发问题探讨 引子 最近有同事写了段代码,负责创建订单的逻辑,代码审查时发现可能会有并发的问题.同事并不认同,他认为他的逻辑是写在存储过程中的,应该没有问题. 代码的逻辑大概是(伪代码): begin transaction if 查询到客户存在进行中的订单 rollback transaction if 查询到设备存在进行中的订单 rollback transaction 插入订单 commit transaction 下面针对这个逻辑进行分析,为什么这个事务会出现并发问题.

Microsoft SQL Server中的事务与并发详解

本篇索引: 1.事务 2.锁定和阻塞 3.隔离级别 4.死锁 一.事务 1.1 事务的概念 事务是作为单个工作单元而执行的一系列操作,比如查询和修改数据等. 事务是数据库并发控制的基本单位,一条或者一组语句要么全部成功,对数据库中的某些数据成功修改; 要么全部不成功,数据库中的数据还原到这些语句执行之前的样子. 比如网上订火车票,要么你定票成功,余票显示就减一张; 要么你定票失败获取取消订票,余票的数量还是那么多.不允许出现你订票成功了,余票没有减少或者你取消订票了,余票显示却少了一张的这种情况

MySql 事务,并发问题 ,锁机制 <转>

Mysql事务,并发问题,锁机制 1.什么是事务 事务是一条或多条数据库操作语句的组合,具备ACID,4个特点. 原子性:要不全部成功,要不全部撤销 隔离性:事务之间相互独立,互不干扰 一致性:数据库正确地改变状态后,数据库的一致性约束没有被破坏 持久性:事务的提交结果,将持久保存在数据库中 2.事务并发会产生什么问题 1)第一类丢失更新:在没有事务隔离的情况下,两个事务都同时更新一行数据,但是第二个事务却中途失败退出, 导致对数据的两个修改都失效了. 例如: 张三的工资为5000,事务A中获取

Mysql事务,并发问题,锁机制-- 幻读、不可重复读(转)

1.什么是事务 事务是一条或多条数据库操作语句的组合,具备ACID,4个特点. 原子性:要不全部成功,要不全部撤销 隔离性:事务之间相互独立,互不干扰 一致性:数据库正确地改变状态后,数据库的一致性约束没有被破坏 持久性:事务的提交结果,将持久保存在数据库中 2.事务并发会产生什么问题 1)第一类丢失更新:在没有事务隔离的情况下,两个事务都同时更新一行数据,但是第二个事务却中途失败退出, 导致对数据的两个修改都失效了. 例如: 张三的工资为5000,事务A中获取工资为5000,事务B获取工资为5

六个可以替代传统事务解决并发问题的建议

增删改查是大部分框架的功能,如果有两个并发请求修改同一个数据,这个时候,你会怎么办?或者插入本来应该是唯一却重复的数据时应该怎么办?再或者插入和修改时有其它辅助动作比如保存到另外的表,这些情况,有什么好的解决方案? 我想最开始,你会首先想到“事务”,事务确实能够让一组操作一起可靠安的全执行,他们要么全部执行,要么一个也别想执行.但如果有两个同时发生的并发事务怎么办?使用事务隔离级别,这是ACID中的定义,关系数据库内部机制中就是这么做的. 但是,如果使用隔离级别,比如可串行化serializab

ServiceStack.Redis常用操作 - 事务、并发锁

一.事务 使用IRedisClient执行事务示例: using (IRedisClient RClient = prcm.GetClient()) { RClient.Add("key",1); using (IRedisTransaction IRT = RClient.CreateTransaction()) { IRT.QueueCommand(r => r.Set("key", 20)); IRT.QueueCommand(r => r.Inc

ServiceStack.Redis常用操作 - 事务、并发锁_转

一.事务 使用IRedisClient执行事务示例: using (IRedisClient RClient = prcm.GetClient()) { RClient.Add("key",1); using (IRedisTransaction IRT = RClient.CreateTransaction()) { IRT.QueueCommand(r => r.Set("key", 20)); IRT.QueueCommand(r => r.Inc

Hibernate事务与并发问题处理(乐观锁与悲观锁)

目录 一.数据库事务的定义 二.数据库事务并发可能带来的问题 三.数据库事务隔离级别 四.使用Hibernate设置数据库隔离级别 五.使用悲观锁解决事务并发问题 六.使用乐观锁解决事务并发问题 一.数据库事务的定义 数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作.事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源.通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠

Mysql事务,并发问题,锁机制

1.什么是事务 事务是一条或多条数据库操作语句的组合,具备ACID,4个特点. 原子性:要不全部成功,要不全部撤销 隔离性:事务之间相互独立,互不干扰 一致性:数据库正确地改变状态后,数据库的一致性约束没有被破坏 持久性:事务的提交结果,将持久保存在数据库中 2.事务并发会产生什么问题 1)第一类丢失更新:在没有事务隔离的情况下,两个事务都同时更新一行数据,但是第二个事务却中途失败退出, 导致对数据的两个修改都失效了. 例如: 张三的工资为5000,事务A中获取工资为5000,事务B获取工资为5