2012-02-05 48 views
0

我在早些時候使用事務時遇到了一些問題。希望有人能幫我弄明白。我會感謝任何幫助。謝謝。使用索引列和非索引列來更新來自不同事務的數據有什麼區別?

MySQL表結構:

create table test (
    id int not null, 
    someid int, 
    name varchar(50), 
    update_date datetime 
); 
primary key : id (auto-inc) 
index1 : id (unique) 
index2 : id, update_date (non-unique) 

Java方法:

// consider this method is Transaction 1 
method1() { 
    A. set session transaction isolation level read commited; 
    B. select update_date from test where someid = 1; 
    C. insert into test values (some new data..); 
    D. select update_date from test where someid = 1; 
} 

// consider this method is Transaction 2 
methodb() { 
    E. (start with default transaction isolation level - repeatable read) 
    F. update test set udpate_date = now() where someid = 1; 
} 

這裏是我做的:

  1. 執行方法1(),打破(在Eclipse中設置斷點)在D
  2. 執行方法2()併發

請注意,「someid」不在索引中,但它存儲與「id」完全相同的數據。

然後,我只有等待,只要我不提交交易1,或者最終交易超時就結束。但如果我改變了從哪裏條款到F id = 1,它會工作得很好,沒有任何等待。在這裏我感到困惑,因爲我沒有鎖定該表或任何行。如果我這樣做,不應該這樣做,對吧?

有人可以告訴我爲什麼會發生這種情況嗎?謝謝!

回答

1

條件someId = 1要求數據庫系統掃描整個表,因爲沒有索引。 insert語句可以插入someid = 1的行,並因此影響第二個事務的結果。

使用where id = 1,dbs可以確定只有一行受到F語言的影響。插入語句不會更改此行。

我只是想知道,隔離級別是否會影響執行?

+0

謝謝你的回覆!這對於更新是如何實現是有意義的,至少我認爲是這樣。嗯,我對交易並不熟悉,但相信隔離級別會影響更新聲明,至少對我來說很難相信:-) – redfoxlee 2012-02-05 11:05:20

+0

btw:好像隔離級別會影響鎖定模式。但在這種情況下,我看不到READ COMMITED和REPEATABLE READ之間的區別。 – redfoxlee 2012-02-05 15:05:34

1

我不是MySQL的併發控制專家,但我猜你正在看到鎖定的影響:直到第一個事務提交,第二個無法知道第一個事務插入的行是否會被提交,所以必須停下來。

第一事務完成後,方可第二個事務繼續,並且:

  • 更新的行(如果第一個事務提交)
  • 或無法更新行(如果第一個事務回滾,所以該行並未實際插入)。

現在的問題是:爲什麼沒有發生索引id?您確定您使用與someid相同的價值進行交易嗎?您是否更改了兩項交易的WHERE條款?

+0

謝謝你的回覆,首先。我的目標是從「測試」中複製一些數據作爲模板並將它們插回到同一張表中。所以我必須確保我有一個正確的副本,這就是爲什麼我確實使用了上述方法。是的,我確定我對這兩筆交易使用了相同的價值。那麼,我不知道,現在看來tkr的答案在這裏有一定意義:-)。任何其他想法? – redfoxlee 2012-02-05 10:51:17

+0

@redfoxlee事實上,第二個事務在提交第一個事務時會解鎖_exactly_,這表明存在某種鎖定。你使用什麼存儲引擎?我發現[MyISAM](http://dev.mysql.com/doc/refman/5.6/en/internal-locking.html)引擎有一個有趣的引用:_「如果有漏洞,併發插入被禁用但啓用當所有的孔都填滿了新的數據時,也會自動進行。「_。也許你只是不幸擊中這些漏洞?你描述的行爲是否一貫發生 - 你測試過多次了嗎? – 2012-02-05 12:55:44

+0

嗯,自從我開始以來,我一直不走運......但確定的是我很幸運,因爲我使用InnoDB引擎:-)。是的,我多次做了這個測試,每次都會發生:-( – redfoxlee 2012-02-05 15:02:20

相關問題