JPA事務併發(樂觀鎖實現隔離機制)
阿新 • • 發佈:2018-11-19
事務(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("==============================沒貨了!!=========================="); } }