如何解決事務操作中狀態不一致的現象?

昨天,一個同學問了一個關於事務處理的一個問題。問題的情景是,有一個機櫃分裏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這個字段上建立一個唯一索引。這樣插入提示出錯就說明設備已經被佔用。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章