1. 程式人生 > >JPA事務併發(樂觀鎖實現隔離機制)

JPA事務併發(樂觀鎖實現隔離機制)

事務(4個特性ACID)

原子性(atomic),事務必須是原子工作單元;對於其資料修改,要麼全都執行,要麼全都不執行
一致性(consistent),事務在完成時,必須使所有的資料都保持一致狀態。
隔離性(insulation),由事務併發所作的修改必須與任何其它併發事務所作的修改隔離
永續性(Duration),事務完成之後,它對於系統的影響是永久性的。

事務併發

通常為了獲得更好的執行效能,各種資料庫都允許多個事務同時執行,這就是事務併發。

事務併發帶來的問題??

①第一類丟失更新:(在秒殺場景會出現問題)
​​​​​​​②髒讀
​​​​​​​③虛讀(幻讀)
​​​​​​​④不可重複讀
​​​​​​​⑤第二類丟失更新

​​​​​​​隔離機制

當併發的事務訪問或修改資料庫中相同的資料(同一行同一列)時,通常需要採取必要的隔離機制。
解決併發問題的途徑是什麼?   --> 採取有效的隔離機制。
怎樣實現事務的隔離呢?    --> 使用鎖

樂觀鎖實現隔離   --> @Version
在bean類裡面新增一個私有欄位Integer version,不由程式設計師維護,由JPA自己維護

ex:

@Version
private Integer version;
public Integer getNum() {
    return num;
}
public void setNum(Integer num) {
    if(num<0){
        throw new RuntimeException("======沒貨了o !!!");
    }
    this.num = num;
}
@Test
    public void testBuy() throws Exception {
        try {
            //第①個事務
            EntityManager entityManager = JPAUtil.getEntityManager();
            //①.開始事務
            entityManager.getTransaction().begin();

            //第②個事務
            EntityManager entityManager2 = JPAUtil.getEntityManager();
            //②.開始事務
            entityManager2.getTransaction().begin();

            //①.查詢產品
            Product product = entityManager.find(Product.class, 1L);
            //②.查詢產品
            Product product2 = entityManager2.find(Product.class, 1L);

            //①.買一個產品(數量 -1)
            product.setNum(product.getNum() - 1);
            //①.提交事務
            entityManager.getTransaction().commit();
            //①.關閉
            entityManager.close();

            //②.買一個產品(數量 -1)
            product2.setNum(product2.getNum() - 1);
            //②.提交事務
            entityManager2.getTransaction().commit();
            //②.關閉
            entityManager2.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("==============================沒貨了!!==========================");
        }
    }