做实战的时候遇到一个问题:
已知有菜品分类(表示菜品的种类),然后还有就是菜品,我们在删除菜品分类的时候要先知道菜品分类下有没有菜品,如果有菜品就不能删除,没有菜品才可以删除。但是这个是否会和添加菜品产生线程安全问题?这边查询数据库没有,但是删除之前,另一个用户添加了该种类下的菜品,但是另一个不知道,就会删除,逻辑就出错了。
但是如果加同步的话,需要添加菜品逻辑和删除逻辑加同一个锁对象把?那么此时删除逻辑,添加菜品以及二者都会被阻塞,性能太差了,那请问有其他解决办法吗(除了直接在sql里添加条件判断)
乐观锁,比如使用版本号或时间戳。你在删除菜品分类之前,检查版本号或时间戳和数据亏对不对得上,对不上,就是别人改了菜品,那就不能删。
悲观锁,就是用行锁或表锁来限制修改数据。删除菜品分类时,给类先加个锁,放被人在你检查前下手,这样,添加菜品的操作就被阻塞了,直到你释放锁才行。但这可能会造成锁定资源过长的问题,还要考虑性能稳不稳。
-使用数据库事务是一种解决方案。在删除菜品分类之前可以使用数据库的唯一约束来确保菜品分类下没有菜品。
该回答引用ChatGPT
_请参考下面的解决方案,如果有帮助,还请点击 “采纳” _
有多种方法可以解决这个问题,不需要加锁,提高性能。
1、使用乐观锁:在删除菜品分类时,检查分类是否有菜品。如果有菜品,则等待一段时间并再次检查。
2、使用悲观锁:在删除菜品分类时,锁定该分类,以防止其他用户对其进行修改。
3、使用数据库事务:在删除菜品分类和添加菜品时,使用数据库事务来确保数据的一致性。
4、使用无锁数据结构:使用无锁数据结构,如CAS或AtomicReference,来避免锁的性能影响。
如果在代码方面用“乐观锁,悲观锁”都觉着不妥, 数据库方面事务也认为不合适, 就可以从业务上尝试操作切碎:
1、菜品分类由店长负责维护,能够上架下架(对其他角色不可见,只标记不删除),下架的分类不能发布菜品。
2、菜品由厨师长负责维护,添加菜品需要店长审批通过。
3、业务保障:下架的菜品分类不能发布菜品,即便(误)添加菜品(垃圾数据),店长也可以拒绝审批或删除, 厨师长也可以自己删除被拒的菜品。
这样业务上也比较合适。
一个常见的解决方案是使用乐观锁,具体来说就是在修改操作时在数据行上加一个版本字段,并在修改时判断版本字段是否满足预期。如果版本字段不满足预期,说明另一个线程已经修改了数据,此次修改操作就不会执行,这样就可以保证数据的一致性。此外,还有一种选择是使用分布式锁来解决该问题,但这需要一个可靠的锁服务器。
其实添加也一样,添加从表数据之前要先判断主表数据是否存在,这里应该有外键约束,否则万一先删后加一样会出错
只要主从表之间有外键约束,那么从表里已经添加了数据,你想删除主表,就会违反约束,操作是不成功的
这里根本一种锁都不需要
有个方案就是删除菜品分类的时候不真正的删除, 加个字段deleted代表状态, 删除就改成状态1下架, 添加新的菜品就把状态改成0激活(不管之前的状态), 可以尝试这种方案
简单来说
一种可行的方案是使用数据库的事务处理。在进行删除菜品分类和添加菜品操作时,都在同一个事务中进行。这样可以保证原子性,在一个事务中失败就会回滚,避免出现逻辑错误。另外,您可以使用乐观锁,例如版本号,来避免并发操作造成的冲突。