覆盤了一下上週寫的代碼,沒注意的情況下在Controller中調用了Service的多個DML操作,這就是妥妥的數據不安全的操作。
我們在Service層配置的事務的隔離級別統一爲DEFAULT,傳播機制爲REQUIRED,也就是說支持當前事務,如果當前沒有事務,則開啓新的事務。而由於Controller層並沒有事務控制,在該層執行多個DML操作,如果其中有部分操作失敗了,就會導致事務的原子性遭到了破壞。
多個增刪改的操作應該置於一個事務中完成。
下面附上Spring事務管理的傳播機制和隔離級別的說明:
傳播屬性 | 值 | 說明 |
---|---|---|
PROPAGATION_REQUIRED | 0 | 支持當前事務,如果當前沒有事務,則新建一個事務,這是Spring的默認屬性 |
PROPAGATION_SUPPORTS | 1 | 支持當前事務,如果當前沒有事務,則以非事務方式運行 |
PROPAGATION_MANDATORY | 2 | 支持當前事務,如果當前沒有事務,則拋出異常 |
PROPAGATION_REQUIRES_NEW | 3 | 新建事務,如果當前存在事務,則將當前事務掛起 |
PROPAGATION_NOT_SUPPORTED | 4 | 以非事務方式運行,如果當前存在事務,則將當前事務掛起 |
PROPAGATION_NEVER | 5 | 以非事務方式運行,如果當前存在事務,則拋出異常 |
PROPAGATION_NESTED | 6 | 如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則以類似PROPAGATION_REQUIRED的形式運行 |
隔離級別 | 值 | 說明 |
---|---|---|
ISOLATION_DEFAULT | -1 | 這是一個PlatfromTransactionManager默認的隔離級別,使用數據庫默認的事務隔離級別 |
ISOLATION_READ_UNCOMMITED | 1 | 最低級別的事務隔離,允許一個事務看到另一個事務未提交的數據。可以產生髒讀、幻讀、不可重複讀的問題。 |
ISOLATION_READ_COMMITED | 2 | 保證事務的數據提交後才能被另一個事務讀取到。 |
ISOLATION_REPEATABLE_READ | 3 | 可以防止髒讀、不可重複讀,但不能避免幻讀。 |
ISOLATION_SERIALIZABLE | 4 | 最高級別,代價高昂。 |
關於髒讀、幻讀、不可重複讀之類問題的概念:
- 髒讀:一個事務讀到另一個事務未提交的更新數據。
- 不可重複讀:一個事務兩次讀同一行數據,可是這兩次讀到的數據不一樣。
- 幻讀:一個事務執行兩次查詢,但第二次查詢比第一次查詢多出了一些數據行。
- 丟失更新:撤消一個事務時,把其它事務已提交的更新的數據覆蓋了。