2010-06-23 48 views
26

在事務中包含select語句有什麼意義?我認爲select語句只是數據庫中的「GET」數據,他們沒有機會回滾某些內容,因爲你無法更改數據。那麼,這是否說我們從不需要在交易中放置選擇語句?我對嗎?在事務中包含select語句有什麼意義?

謝謝。

回答

31

您是對的:在標準isolation levelread committed中,您不需要在事務中包裝select語句。無論是否將它們包裝在事務中,Select語句都將受到保護而不受髒讀的影響。

connection 1:       connection 2: 

             begin transaction 
             update user set name = 'Bill' where id = 1 
select name from users where id = 1 
             rollback transaction 

select語句不會讀取回滾更新:它們沒有被包裝在事務中並不重要。

如果需要repeatable reads,在默認的事務,然後選擇包裝沒有幫助:

connection 1:       connection 2: 

begin transaction 
select name from users where id = 1 
             update user set name = 'Bill' where id = 1 
select name from users where id = 1 
commit transaction 

begincommit語句將不會在這裏幫助:第二select可以讀取舊名,或者可能會讀取新名稱。

不過,如果你在一個較高的隔離級別運行,像serializablerepeatable read,該組將被保護,不可重複讀:

connection 1:       connection 2: 

set transaction isolation level 
    repeatable read 
begin transaction 
select name from users where id = 1 
             update user set name = 'Bill' where id = 1 
select name from users where id = 1    | 
commit transaction        | 
               |--> executed here 

在這種情況下,update將阻塞,直到第一個事務做完了。

較高的隔離級別很少使用,因爲它們可以同時降低可以在數據庫中工作的人數。在最高級別serializable中,報告查詢會暫停任何更新活動。

+0

關於您的最後一段,**爲什麼更新塊會被阻止?**是不是可能更新仍然沒有阻塞,但是第一個事務是可重複讀取的,仍然會繼續使用舊值? – Pacerier 2014-12-30 04:48:02

+0

@Pacerier:可重複讀取表示如果您讀取兩次,第二次讀取將返回相同的結果。與Oracle或PostgeSQL不同,SQL Server不保留舊值。您可以使用['SET READ_COMMITTED_SNAPSHOT ON'](http://msdn.microsoft.com/zh-cn/library/ms345124.aspx)更改此行爲。 – Andomar 2014-12-31 00:25:05

+0

嗯,這很奇怪,似乎是MySQL的默認值。因此,對於SQL服務器,運行'set read_committed_snapshot on'後,說「更新」將不再**阻止是正確的嗎? – Pacerier 2015-01-03 11:23:27

7

您可能會在此次交易中進行其他更新/插入操作。如果訪問數據庫的代碼是以可重用的方式編寫的,那麼您可能不會選擇是否是事務中唯一發生的事情。

您的select語句可能希望在事務期間保持一致,並且與其他事務中發生的數據更改一致。您需要在系統中設置某種isolation level以防止髒讀(讀取另一事務中未提交的更改)或幻讀(讀取另一事務中已提交的更改)。

不用說,通過使用交易你會更好地服務。

4

事務讓你的數據庫的一致視圖。

如果您希望您的選擇在重複它們時返回相同的結果,則事務可以提供該結果。

4

可能不會更改數據,但可能會有其他數據庫連接。

1

如果您確定發生的所有事情都是SELECT,那麼它不需要處於事務中。你是否100%肯定現在和永遠更多它將只是一個SELECT?

5

一個單一的SELECT語句是以原子開始的 - 將它包含在一個事務中是多餘的。如果有多個SELECT語句,則保證沒有人改變任何影響它們的任何內容,直到它們全部完成。

2

另一個原因是使用交易與選擇:

有可能在某些時候,你可能希望從那些參與交易的其他方法調用你的選擇方法,你想選擇參加當前事務。如果您有一個一致的設計,即在事務中執行所有數據庫操作,則任何方法的調用者都知道它將參與其事務。

對於小的前期開發成本,這可能有助於避免稍後嘗試在需求更改或添加新要求時試圖阻礙交易的一些相當大的更改。

相關問題