如何解决事务操作中状态不一致的现象?


👁 关注微信公众号:非典型理科男 回复:加群 加入 技术交流群 获取更多技术文档

欢迎关注 非典型理科男  

回复【疫情】获取新型冠状病毒最新信息和防控手册

回复【JVM】获取《深入理解Java虚拟机:JVM高级特性与最佳实践(最新第二版)》

回复 【JDK】获取JDK相关官方文档

回复 【架构设计】获取架构设计相关资料

回复 【架构师】  获取《架构师经典书目》

回复 【infoq】    获取 《Infoq2019年全年架构师全集》

回复【电子书】   获取 《美团2019技术合集》

回复 【redis】 获取redis独家资料

回复 【微信群】  或者【加群】 免费加入 架构师技术交流群

祝所有粉丝:身体健康,万事遂意
 

昨天,一个同学问了一个关于事务处理的一个问题。问题的情景是,有一个机柜分里n层,每一层放里一些设备。现在有两个线程,分别对机柜里面的设备做操作。操作之前先检查数据库中设备是不是已经被占用,如果被占用则不去操作,没有被占用则去占用被在设备的置标志位。伪代码描述处理过程如下:
 
if(getStateFromDbByDeviceId(DeviceId))
{  
         占用设备....
	 setStateToDbByDeviceId(DeviceId);
}
else
{
	return;
 }
        
这段代码在单线程的时候运行正常,但是在多线程的时候会存在线程安全的问题,而这种线程不安全表现为事务操作的不一致性。A和B进程同时去占用同一个设备d,A检查数据库设备d的状态位false然后去占用,然后这时A虽然占用里设备d,但是没有还没有更新数据库中的状态,B去检查状态仍然可以去占用d。然后A和B同时更新数据库,就造成里数据库的不一致现象。
        解决这种不一致的可以通过应用程序层事务管理或者使用数据库事务来保证占用设备和更新状态在一个原子操作中去完成。应用层可以使用一些框架如Spring实现好的事务去保证,数据库层解决需要修改下数据库的结构。将上面的代码放在一个事务中,就能保证两个线程中的代码不会被乱序执行,A检测设备状态、占用设备和修改数据库要在一步完成,不会受到线程B的打扰。新的数据库结构,新建一个表存储已经被占用设备的id,并且在DeviceId这个字段上建立一个唯一索引。这样插入提示出错就说明设备已经被占用。
 
 
 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

非典型理科男

1毛钱打赏,让作者更有动力噢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值