2017-10-07 51 views
0

我正在運行laravel 5.4並注意到事務回滾不起作用。我在settings.php文件中將我的數據庫引擎設置爲InnoDB,並嘗試DB::rollback();DB::rollBack();(即大寫和小寫b),但它不回滾我的數據庫。Laravel事務回滾似乎不起作用

我寫了一個單元測試波紋管。它創建一個記錄,提交它,然後回滾。然而,最後的斷言失敗了。在回滾之後,數據庫中仍然存在該記錄。有什麼我失蹤?或者是否有laravel的錯誤?

public function testRollback() 
{ 
    $this->artisan('migrate:refresh', [ 
     '--seed' => '1' 
    ]); 

    DB::beginTransaction(); 

    Season::create(['start_date' => Carbon::now(), 'end_date' => Carbon::now(),]); 
    DB::commit(); 
    $this->assertDatabaseHas('seasons', [ 
     'start_date' => Carbon::now(), 'end_date' => Carbon::now(), 
    ]); 

    DB::rollBack(); 
    // This assertion fails. It still finds the record after calling roll back 
    $this->assertDatabaseMissing('seasons', [ 
     'start_date' => Carbon::now(), 'end_date' => Carbon::now(), 
    ]); 
} 

回答

1

本次交易包括三個步驟:

您與DB::beginTransaction或MySQL等同BEGIN TRANSACTION,那麼你執行你需要,然後命令(在這裏是最重要的部分),你要麼COMMIT啓動ROLLBACK

但是,一旦你承諾交易完成了,你不能再回滾了。

更改測試:

public function testRollback() 
{ 
    $this->artisan('migrate:refresh', [ 
     '--seed' => '1' 
    ]); 

    DB::beginTransaction(); 

    Season::create(['start_date' => Carbon::now(), 'end_date' => Carbon::now(),]); 

    $this->assertDatabaseHas('seasons', [ 
     'start_date' => Carbon::now(), 'end_date' => Carbon::now(), 
    ]); 

    DB::rollback(); 

    $this->assertDatabaseMissing('seasons', [ 
     'start_date' => Carbon::now(), 'end_date' => Carbon::now(), 
    ]); 
} 

這應該是因爲工作,直到事務回滾數據庫「認爲」的紀錄就在那裏。

在實踐中使用你想用什麼在the docs建議交易時,例如:

DB::transaction(function() 
{ 
    DB::table('users')->update(array('votes' => 1)); 

    DB::table('posts')->delete(); 
}); 

這將確保包裝操作的原子,如果有異常的函數體中拋出將回滾(你如果需要的話,也可以將自己作爲中止的手段)。

1

不能回滾一旦你commit.As我可以看到你已經使用提交

DB::commit(); 

回滾之前

所以你只能回滾時,它會未能提交。你可以使用try catch塊

DB::beginTransaction(); 
    try { 
     DB::insert(...); 
     DB::commit(); 
    } catch (\Exception $e) { 
     DB::rollback(); 

    } 
1

Emmm ...你誤會了事務是如何工作的。

開始事務後,您可以提交它或回滾它。承諾意味着在到目前爲止的事務處理中對數據庫所做的所有更改都將在數據庫中「最終確定」(即永久化)。只要你承諾,沒有什麼可以回滾的。

如果你想回滾,你必須這樣做之前你提交的。回滾將使數據庫進入開始交易之前的狀態。

這意味着你到底有兩種選擇:

1)開始事務,然後提交到目前爲止所做的所有更改。

2)開始一個事務,然後回滾到目前爲止所做的所有更改。

對於交易,即結束交易,提交和回滾均爲最終動作。當提交或回滾時,交易從數據庫的角度完成。

你也可以看看這個以下列方式:

通過啓動交易時,你是在告訴所有的以下變化是初步/臨時數據庫。完成更改後,您可以告訴數據庫使這些更改永久(通過提交),或者告訴數據庫丟棄(回退)更改(通過回滾)。

回滾後,更改將丟失,因此無法再次提交。在您提交之後,這些更改是永久的,因此無法回滾。只有在更改處於臨時狀態時,纔可以進行提交和回滾。