2014-02-15 53 views
4

如果我在某個地方錯了,請糾正我。當@Transactional註釋的方法被多個實例並行命中時會發生什麼?

我有在我的交易沒有被保存到數據庫和某種形式的賽車發生了問題,它搞砸了的數據。該應用程序被多個實例並行命中。我已經使用了@Transactional,我知道這是與數據庫進行交易,並且在方法返回時提交交易。

的問題是,不打它通過多個實例仍保持每擊的東西這一項交易,或它不處理的情況和數據會搞砸,因爲賽車的嗎?

可以針對給定條件建議解決方案嗎?

+0

你能發表一些代碼嗎?你的服務/ dao/instance是否可以共享實例? –

回答

2

@Transactional是不相關的同步。它只是確保你的流程成功或失敗。每次擊中都有自己的流量和自己的成功或失敗。

我猜您遇到是由於使用共享數據。

例如。如果你有一個類Foo,看起來像這樣:

public class Foo { 
    private static boolean flag = true; 

    @Transactional 
    public void doSomething() { 
     flag = false; 
    } 
} 

在這種情況下,不要緊,你有很多Foo實例,因爲它們都使用相同的flag

另一種情況是,如果您有一個Foo實例(如果您使用諸如Spring之類的話很常見),並且您的數據已針對此實例進行更改。你可以看一下同Foo例子,只是刪除staticflag

public class Foo { 
    private boolean flag = true; 

    @Transactional 
    public void doSomething() { 
     flag = false; 
    } 
} 

在其中的任意一種你需要以某種方式同步數據的變化情況。它與@Transactional無關。

+0

如果你正在管理的數據直接與tx相關,那麼使用Spring的'TransactionSynchronizationManager'和子類'TransactionSynchronization'是有意義的。這將確保數據狀態與現有的tx狀態匹配。 – AngerClown

2

將事務數據庫事務和行爲是數據庫引擎相關的,但它通常以這種方式工作:

  1. 一個線程進入方法。
  2. 線程輸入相同或任何其他交易方法。 它不阻擋@Transactional不是關於同步
  3. 一個線程執行任何阻止數據庫資源的查詢。例如。 SELECT * FROM MYTABLE FOR UPDATE;
  4. 另一個線程嘗試執行任何需要同一數據庫資源。例如。 UPDATE MYTABLE SET A = A + 1;它阻止
  5. 該獲取的鎖步完成事務方法成功地製造隱提交或失敗暗示它們回滾線程。
  6. 被阻塞的線程喚醒並繼續,因爲它現在可以獲取被鎖定的資源。
相關問題