首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

删除一条记录,然后在同一Spring事务中进行选择,仍会返回已删除的记录

在同一Spring事务中进行选择,仍会返回已删除的记录的原因是因为Spring事务的隔离级别默认为READ_COMMITTED(读已提交),该隔离级别下,事务可以读取到其他事务已经提交的数据。

当删除一条记录时,如果在同一事务中进行选择操作,即使该记录已经被删除,由于事务还未提交,所以选择操作仍能读取到该记录。只有当事务提交后,其他事务才能看到删除的结果。

为了解决这个问题,可以通过以下两种方式进行处理:

  1. 在删除记录后,手动清除缓存:在删除记录后,通过调用缓存的清除方法,将该记录从缓存中移除。这样在同一事务中进行选择操作时,会从数据库中读取最新的数据,而不会返回已删除的记录。
  2. 在选择操作中使用悲观锁:在选择操作中使用悲观锁(如数据库的行级锁),可以确保在同一事务中进行选择操作时,读取到的数据是最新的数据,而不会返回已删除的记录。可以通过在选择操作的SQL语句中添加FOR UPDATE语句来实现悲观锁。

需要注意的是,以上两种方式都需要在同一事务中进行操作,以确保事务的一致性和隔离性。同时,具体的实现方式可能会因数据库类型、框架版本等因素而有所差异。

推荐的腾讯云相关产品:腾讯云数据库MySQL、腾讯云数据库TDSQL、腾讯云分布式数据库TDSQL-C、腾讯云数据库TBase等。您可以通过访问腾讯云官网(https://cloud.tencent.com/)了解更多关于这些产品的详细信息。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

分布式服务 API 的幂等设计方案 & Spring Boot + Redis 拦截器实现实例

但是删除要注意ABA的问题,即上一次执行删除成功了但是返回了超市,在第二次重试执行前,又插入了同样的一条数据,那么第二次重试执行就会把本不应该删除的数据给删除了。...2、每次处理完请求之后,必须有一个记录标识这个请求处理过了,比如说常见的方案是在mysql中记录个状态啥的,比如支付之前记录一条这个订单的支付流水,而且支付流水采 3、每次接收请求需要进行判断之前是否处理过的逻辑处理...执行这条sql的时候,如果有多个线程同时到达这条代码,数据内部会保证update同一条记录会排队执行,最终最有一条update会执行成功,其他未成功的,他们的num为0,然后根据num来进行提交或者回滚操作...⑦ 服务端根据 Redis 中是否存该 key 进行判断,如果存在就将该 key 删除,然后正常执行业务逻辑。如果不存在就抛异常,返回重复提交的错误信息。...中的token和用户携带的token不一致,也返回false;有且一致,说明是第一次访问,就将redis中的token删除,然后返回true。

83130

​踩坑|以为是Redis缓存没想到却是Spring事务!

一开始以为缓存的维护策略不对,导致数据库和redis出现数据不一致的情况。但是经过进一步分析日志,发现问题并不是在Redis而是在Spring事务。...场景介绍   业务场景如下:用户绑定了设备,需要显示在设备列表内,并且可以查看设备信息。   当用户绑定了一个设备,我需要在数据库内新增一条绑定记录。...如果用户再次绑定同一个设备,会将原先的记录解绑,再生成一条新的绑定记录,由于是同一个设备覆盖绑定,则不会去修改用户策略。   如果在设备端或者手机端,进行解绑操作。...并且是由自身的代理对象self调用的。根据Spring的事务传播性来讲,最外层开启了事务,并且通过代理对象调用内部方法,该内部方法也是具有事务的。...所以避免在耗时的操作里加上事物,也就避免了上述问题的产生。 总结   在实际开发中,我们可能一不小心就掉进了Spring事务的坑里了,所以对于事务我们需要特别小心。

27240
  • MySQL InnoDB MVCC机制

    同一事务的两次相同查询语句都是同样结果, 其他事务修改记录不影响当前事务, 特殊情况是会看到同一事务中先前语句所做的更新, 所以对于普通select(快照读)来说, MVCC是解决了脏读/不可重复读/幻行的...在MySQL中, 实际上每条记录在更新的时候都会同时记录一条回滚操作到undolog(undolog默认在mysql的data文件夹中)中....ReadView的时候会删除回滚日志, 即该undolog不再被需要, 但insert的undolog日志在事务结束后可以立即删除, 因为如果某个事务ID=100新增了一条记录,那么在这个事务版本之前这个记录是不存在的...如果没有找到匹配的记录,则无需在聚集索引中查找。如果找到匹配的记录,即使记录被标记删除,也会在聚集索引中查找记录 5....只是InnoDB发现当前行的事务id已经被更新过, 所以再去查询undolog中的版本记录, 最终根据会话C开启事务时创建的ReadView返回会话B修改后生成的数据版本 ref: https://www.cnblogs.com

    94500

    深入浅出MyBatis:MyBatis与Spring集成及实用场景

    AOP AOP称为面向切面编程,所谓切面,是说在正常逻辑中插入一些逻辑处理代码,比如插入日志记录、事务管理等代码,其中,日志记录和事务管理就是切面。...这就是切入点,Spring可以通过正则进行配置; 切面:上面已经介绍了,日志记录、事务管理等需要处理的逻辑对象,就是切面; 连接点:它是在程序运行中根据不同的通知来实现的程序段,通知包括,前置通知、后置通知...、异常后通知、正常返回后通知、环绕通知; Spring 事务管理 在编写业务代码时,一个业务方法可能涉及多张表或多条sql语句,同一条表数据可能会被同时访问,数据库的事务控制很重要,通过Spring AOP...事务隔离级别 读未提交:可能出现脏读问题,一个事务读取另一个事务未提交的数据; 读已提交:可能出现不可重复读问题,针对同一条记录,同一个事务前后可能读取不同的数据; 可重复读:可能出现幻读问题,针对删除和插入记录...,同一个查询条件,同一个事务返回的记录数可能不同; 序列化:所有操作会按顺序执行; MySql默认隔离级别为可重复读。

    90890

    面试官:消息队列中,消息可靠性、重复消息、消息积压、利用消息实现分布式事务如何实现...

    如果Broker没有收到消费确认响应,下次拉消息的时候还会返回同一条消息,确认消息不会在网络传输过程中丢失,也不会因为客户端在执行消费逻辑中出错导致丢失 在编写消费代码时需要注意的是,不要在收到消息后就立即发送消费确认...ID这两个字段联合起来创建一个唯一约束,这样对于相同的转账单ID和账户ID,表里至多只能存在一条记录 这样,消费消息的逻辑可以变为:在转账流水表中增加一条转账记录,然后再根据转账记录,异步操作更新用户余额即可...在转账流水表增加一条转账记录这个操作中,由于在这个表中预先定义了账户ID转账单ID的唯一索引,对于同一个转账单同一个账户只能插入一条记录,后续重复的插入操作都会失败,这样就实现了一个幂等的操作 只要是支持类似...因为从购物车删除已下单商品这个步骤,并不是用户下单支付这个主要流程中必需的步骤,使用消息队里来异步清理购物车是更加合理的设计 对于订单系统来说,它创建订单的过程中实际上执行了2个步骤的操作: 在订单库中插入一条订单数据...在订单库中创建一条订单记录,并提交订单库的数据库事务。

    55910

    被百度严格拷打 62 分钟,汗流浃背!

    换句话说,浅拷贝只是创建一个新的对象,然后将原对象的字段值复制到新对象中,但如果原对象内部有引用类型的字段,只是将引用复制到新对象中,两个对象指向的是同一个引用对象。...选择排序(Selection Sort):通过不断选择未排序部分的最小(或最大)元素,并将其放置在已排序部分的末尾(或开头)。...然后有两个并发的事务,事务 A 只负责查询余额,事务 B 则会将我的余额改成 200 万,下面是按照时间顺序执行两个事务的行为: 在不同隔离级别下,事务 A 执行过程中查询到的余额可能会不同: 在「读未提交...一个事务在插入一条记录的时候,需要判断插入位置是否已被其他事务加了间隙锁(next-key lock 也包含间隙锁)。...当事务 A 还没提交的时候,事务 B 向该表插入一条 id = 4 的新记录,这时会判断到插入的位置已经被事务 A 加了间隙锁,于是事物 B 会生成一个插入意向锁,然后将锁的状态设置为等待状态,此时事务

    45910

    消息队列中:消息可靠性、重复消息、消息积压、利用消息实现分布式事务

    如果Broker没有收到消费确认响应,下次拉消息的时候还会返回同一条消息,确认消息不会在网络传输过程中丢失,也不会因为客户端在执行消费逻辑中出错导致丢失 在编写消费代码时需要注意的是,不要在收到消息后就立即发送消费确认...ID这两个字段联合起来创建一个唯一约束,这样对于相同的转账单ID和账户ID,表里至多只能存在一条记录 这样,消费消息的逻辑可以变为:在转账流水表中增加一条转账记录,然后再根据转账记录,异步操作更新用户余额即可...在转账流水表增加一条转账记录这个操作中,由于在这个表中预先定义了账户ID转账单ID的唯一索引,对于同一个转账单同一个账户只能插入一条记录,后续重复的插入操作都会失败,这样就实现了一个幂等的操作 只要是支持类似...,然后清理购物车,在购物车中删除订单中的商品 问题的关键点集中在订单系统,创建订单和发送消息这两个步骤要么都操作成功,要么都操作失败,不允许一个成功而另一个失败的情况出现 1、什么是分布式事务?...在订单库中创建一条订单记录,并提交订单库的数据库事务。

    2.1K20

    消息可靠性、重复消息、消息积压、利用消息实现分布式事务

    如果Broker没有收到消费确认响应,下次拉消息的时候还会返回同一条消息,确认消息不会在网络传输过程中丢失,也不会因为客户端在执行消费逻辑中出错导致丢失 在编写消费代码时需要注意的是,不要在收到消息后就立即发送消费确认...ID这两个字段联合起来创建一个唯一约束,这样对于相同的转账单ID和账户ID,表里至多只能存在一条记录 这样,消费消息的逻辑可以变为:在转账流水表中增加一条转账记录,然后再根据转账记录,异步操作更新用户余额即可...在转账流水表增加一条转账记录这个操作中,由于在这个表中预先定义了账户ID转账单ID的唯一索引,对于同一个转账单同一个账户只能插入一条记录,后续重复的插入操作都会失败,这样就实现了一个幂等的操作 只要是支持类似...,然后清理购物车,在购物车中删除订单中的商品 问题的关键点集中在订单系统,创建订单和发送消息这两个步骤要么都操作成功,要么都操作失败,不允许一个成功而另一个失败的情况出现 1、什么是分布式事务?...在订单库中创建一条订单记录,并提交订单库的数据库事务。

    1.2K20

    微服务架构-消息队列常见问题和解决方案

    如果Broker没有收到消费确认响应,下次拉消息的时候还会返回同一条消息,确认消息不会在网络传输过程中丢失,也不会因为客户端在执行消费逻辑中出错导致丢失 在编写消费代码时需要注意的是,不要在收到消息后就立即发送消费确认...ID这两个字段联合起来创建一个唯一约束,这样对于相同的转账单ID和账户ID,表里至多只能存在一条记录 这样,消费消息的逻辑可以变为:在转账流水表中增加一条转账记录,然后再根据转账记录,异步操作更新用户余额即可...在转账流水表增加一条转账记录这个操作中,由于在这个表中预先定义了账户ID转账单ID的唯一索引,对于同一个转账单同一个账户只能插入一条记录,后续重复的插入操作都会失败,这样就实现了一个幂等的操作 只要是支持类似...因为从购物车删除已下单商品这个步骤,并不是用户下单支付这个主要流程中必需的步骤,使用消息队里来异步清理购物车是更加合理的设计 对于订单系统来说,它创建订单的过程中实际上执行了2个步骤的操作: 1、在订单库中插入一条订单数据...在订单库中创建一条订单记录,并提交订单库的数据库事务。

    56920

    Java岗大厂面试百日冲刺 - 日积月累,每日三题【Day04】——Java高级篇

    脏读 A事务对一条记录进行修改 尚无提交 B事务已经看到了A的修改结果 若A发生回滚 B读到的数 据就是错误的 不可重复读         A事务对一条记录进行修改 尚无提交 B事务第一次查询该记录...看到的是修改之后的结果 此时 A发生回滚 B事务又一次查询该记录 看到的是回滚的结果 同一个事务内 B两次查询结果不一致 这 就是不可重复读 幻读         A事务对所有记录进行修改 尚未提交...此时B事务创建了一条新记录 A B都提交 A查看所有数 据 发现有一条数据没有被修改 因为这是B事务新增的 就像看到幻象一样 这就是幻读 非重复度和幻像读的区别:         非重复读是指同一查询在同一事务中多次进行...,由于其他提交事务所做的修改或删除,每次返回不同的结果集,此时发生非重复读。         ...幻像读是指同一查询在同一事务中多次进行,由于其他提交事务所做的插入操作,每次返回不同的结果集,此时发生幻像读。

    19330

    Hibernate_day01总结

    tx.commit(); // 释放资源 session.close(); } 1.5.4 删除一条记录: @Test /** * 删除一条记录 */ publicvoid delete() { //...Transaction tx = session.beginTransaction(); // 执行操作: // 删除方式一:创建新对象然后删除....:Java中区分是否是同一个对象.对象的地址.数据库中区分是否是同一条记录.主键.Hibernate中区分对象在内存中是否是同一个?...(short,int,long).采用的是hibernate中的自动增长,不是使用数据库底层的自动增强. * select max(id) from Customer; 将最大值加1作为下一条记录的主键.... assigned :主键Hibernate不进行管理.需要自己在程序中设置主键. foreign :主要使用在一对一的关联关系中. 1.8.5 复合主键的配置: 配置: <hibernate-mapping

    1.3K90

    Mysql详解

    3)使用自增主键则可以避免上述问题: 【1】自增主键值是顺序的,所以Innodb把每一条记录都存储在一条记录的后面。...【2】并发事务处理带来的问题 问题 说明 更新丢失(Lost Update)或脏写 当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题–...脏读(Dirty Reads) 一个事务正在对一条记录做修改,在这个事务完成并提交前,这条记录的数据就处于不一致的状态;这时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些“脏”数据,...【8】对于删除的情况可以认为是update的特殊情况,会将版本链上最新的数据复制一份,然后将trx_id修改成删除操作的trx_id,同时在该条记录的头信息(record header)里的(deleted_flag...)标记位写上true,来表示当前记录已经被删除,在查询时按照上面的规则查到对应的记录如果delete_flag标记位为true,意味着记录已被删除,则不返回数据。

    56720

    科普 | 几个小案例帮你搞懂MVCC实现原理

    悲观锁保证在同一时间只能有一个线程访问,默认数据在访问的时候会产生冲突,然后在整个过程都加上了锁。...当删除一条数据时会将版本链上最新的数据复制一份,然后将 trx_id 修改为删除时的 trx_id,同时在该记录的头信息中存在一个 delete flag 标记,将这个标记写上 true,用来表示当前记录已经删除...read-view 是根据在同一事务中第一条快照读产生的,再来看一个案例。...此时的事务 ID101 也再对数据更新两次,然后在进行查询看一下会返回什么值: ? 经过案例一、案例二的熟悉,现在对 undo log 的版本链和对比规则已经有了一定的了解了吧!...小结:在同一个事务中进行查询,会沿用第一次查询语句生成的 read-view(前提是隔离级别是在可重复读)。 通过以上的四个案例,在版本链寻找过程中,可以总结出一个小技巧: ?

    1.5K10

    spring事务(上)

    在T1时刻开启了事务1,T2时刻开启了事务2, 在T3时刻事务1从数据库中取出了id="402881e535194b8f0135194b91310001"的数据, T4时刻事务2取出了同一条数据, T5...在T1时刻开启了事务1,T2时刻开启了事务2, T3时刻事务1从数据库中查询所有记录,记录总共有一条, T4时刻事务2向数据库中插入一条记录,T6时刻事务2提交事务。...在T1时刻开启了事务1,T2时刻开启了事务2, 在T3时刻事务1从数据库中取出了id="402881e535194b8f0135194b91310001"的数据,此时age=20, T4时刻事务2查询同一条数据...这种情况就是"不可重复读(unrepeated read)" 第二类丢失更新(second lost updates) 覆盖丢失 不可重复读的特殊情况,如果两个事务都读取同一行,然后两个都进行写操作,并提交...写锁比读锁的优先级更高,即使有读操作已排在队列中,一个被申请的写锁仍可以排在所队列的前列。 行级锁仅对指定的记录进行加锁 这样其它进程可以对同一个表中的其它记录进行读写操作。

    77930

    一篇文章彻底搞懂Mysql事务相关原理

    客户端A创建一个包含两个索引记录(90和102)的表,然后启动一个事务,该事务将排他锁放置在ID大于100的索引记录上。...此外,删除在内部被视为更新,在该更新中,行中的特殊位被设置为将其标记为已删除。每行还包含一个7字节的 DB_ROLL_PTR字段,称为滚动指针。回滚指针指向写入回滚段的撤消日志记录。...当二级索引记录被删除标记或二级索引页由较新的事务更新时,InnoDB在聚集索引中查找数据库记录。...而不是从索引结构中返回值,而是InnoDB在聚集索引中查找记录。...将选择好的索引添加到表中。然后,您的查询需要扫描较少的索引记录,因此设置较少的锁。使用EXPLAIN SELECT以确定哪些索引MySQL认为最适合您的查询。 使用更少的锁定。

    85210

    Spring 事务介绍(一)之 数据库的事务的基本特性

    Spring 事务介绍(一)之 数据库的事务的基本特性 数据库的事务的基本特性 事务是区分文件存储系统和Nosql数据库重要特性之一,其存在的意义是为了保证即时在并发的情况下,也能正确的执行crud操作...很多时候我们有些业务对事务的要求是不一样的,所有数据库中设计了四种隔离级别,供用户基于业务进行选择。...不可重复读: 在同一事务中,多次读取同一数据返回的结果有所不同,换句话说,后面读取可以读到另一个事务已提交的更新数据,相反,“可重复读”在同一事务中多次读取数据时,能够保证所读数据一样,也就是后续读取不能读取到另一事务所提交的更新数据...幻读场景描述: 设置id为主键,在两个同时进行的事务中,如果此时事务t1做插入(id=1),事务t2按主键查询(id=1)因为此时为TRANSACTION_REPEATABLE_READ级别 ,所以查询为空...,然后进行插入(id=1) 此时会出现主键冲突的异常,这种情况主要是由MVCC导致的,t2查询的数据因为没有改动所以是之前保留的查询数据,为快照版本,但实际上数据库已经新增了一条,此时进行插入,就抛出主键冲突异常了

    63320

    MVCC

    ,mysql中使用了大量缓存,修改操作时会直接修改内存,而不是立刻修改磁盘,事务进行中时会不断的产生redo log,在事务提交时进行一次flush操作,保存到磁盘中。...为演示,插入提交后,该undo log被删除 二、 现在来了一个事务1对该记录的name做出了修改,改为Tom 在事务1修改该行(记录)数据时,数据库会先对该行加排他锁 然后把该行数据拷贝到undo log...的副本记录,既表示我的上一个版本就是它 事务提交后,释放锁 三、 又来了个事务2修改person表的同一个记录,将age修改为30岁 在事务2修改该行数据时,数据库也先为该行加锁 然后把该行数据拷贝到undo...那就是2,回滚指针指向刚刚拷贝到undo log的副本记录 事务提交,释放锁 记录版本链 从上面,我们就可以看出,同一记录的多次修改,会导致该记录的undo log成为一条记录版本线性表,既链表,undo...和undo log 做对比得到结果 比较规则: 依次比较记录版本链中每一条记录,符合规则就返回该条数据,不符合根据回滚指针取链路中的下一条数据; trx_id为记录版本链里的DB_TRX_ID 1、如果

    78130

    干货 | 携程最终一致和强一致性缓存实践

    由于有多个触发源,不同的触发源之间可能会对同一条数据的缓存更新请求出现并发,此外可能出现同一条数据在极短时间内(如1秒内)更新多次,无法区分数据更新顺序,因此需要做两方面的操作来确保数据更新的准确性。...举个例子:假设同一秒内同一条数据出现了两次更新,value=1和value=2,期望最终缓存中的数据是value=2。...事务提交后,对应的变更记录持久化,之后进行删除缓存,若缓存删除成功,则将对应的记录表数据也删除掉。...若缓存删除失败,则可根据记录表的数据进行补偿删除,而在redis的恢复流程中,需要校验记录表中是否存在数据,若存在则表示有变更后的数据对应的缓存未清除,不可进行缓存读取的恢复。...简单来说,该机制提供了Spring环境中事务执行前后的AOP功能,可以在spring事务的执行前后添加自己的操作,如下所示(代码和注释经过了简化): public interface TransactionSynchronization

    1.6K32

    这六个 MySQL 死锁案例,能让你理解死锁的原因!

    起初业务程序思路是这样的: 投资人投资后,将金额随机分为几份,然后随机从借款人表里面选几个,然后通过一条条select for update 去更新借款人表里面的余额等。...众所周知,InnoDB上删除一条记录,并不是真正意义上的物理删除,而是将记录标识为删除状态。(注:这些标识为删除状态的记录,后续会由后台的Purge操作进行回收,物理删除。...但是,删除状态的记录会在索引中存放一段时间。) 在RR隔离级别下,唯一索引上满足查询条件,但是却是删除记录,如何加锁?...因此,为了修改一条记录,InnoDB内部如何处理: 根据给定的查询条件,找到对应的记录所在页面; 对页面加上X锁(RWLock),然后在页面内寻找满足条件的记录; 在持有页面锁的情况下,对满足条件的记录加事务锁...,有可能删除到同一条记录,并且保证删除的记录一定存在; 事务的隔离级别设置为Repeatable Read,同时未设置innodb_locks_unsafe_for_binlog参数(此参数默认为FALSE

    97340

    Spring认证中国教育管理中心-Spring Data Redis框架教程二

    这些操作在 上可用RedisTemplate。但是,RedisTemplate不能保证在同一个连接中运行事务中的所有操作。...以前,这些方法直接从连接器返回事务的结果。这意味着数据类型通常与从 的方法返回的数据类型不同RedisConnection。例如,zAdd返回一个布尔值,指示元素是否已添加到排序集中。...在正在进行的事务期间发出的命令被排队,并且仅在提交事务时应用。 Spring Data Redis 在正在进行的事务中区分只读和写命令。...当您需要连续发送多个命令时,流水线可以提高性能,例如将许多元素添加到同一个 List。 Spring Data Redis 提供了多种RedisTemplate在管道中运行命令的方法。...在results List包含了所有的弹出项目。RedisTemplate在返回之前使用其值、哈希键和哈希值序列化器对所有结果进行反序列化,因此前面示例中的返回项是字符串。

    1.3K20
    领券