您的位置:首页 > 数据库

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

2015-09-06 16:38 288 查看
昨天,一个同学问了一个关于事务处理的一个问题。问题的情景是,有一个机柜分里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这个字段上建立一个唯一索引。这样插入提示出错就说明设备已经被占用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息