說到Spring框架內的事務隔離級別,估計沒幾個人不知道。但就其實現原理(看spring源碼的實現方式)都覺得頭痛。網上很多源碼分析也分析的不錯,但個人感覺都沒有說到重點。或者換種更讓人簡單理解的方式。
好了廢話不多說。我們來看個例子
@Transactional
public void a() {
//更新數據
b();
//...
//回滾數據
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void b() {
//更新數據
}
大家看到上面的代碼塊,很容的明白,a方法事務不管是回滾還是提交與b方法互不干涉。同理b方法也是一樣
其它的如PROPAGATION_NESTED這種,網上都說了借助於mysql的savepoint。唯獨PROPAGATION_NEW說的玄乎。。
網上都說b方法把a方法內的事務給掛起來了。其實怎么掛的,很少有人說。
...
...
這里省略N字
...
...
其實很簡單,創建兩個連接。
例子如下:
public class TransactionTest {
@Test
public void test() throws Exception {
Connection conn = getConnection();
conn.setAutoCommit(false);
Statement statement = conn.createStatement();
statement.executeUpdate("update test_tl set addr='abc' where id=2");
transaction2();
conn.rollback();
}
public void transaction2() throws Exception {
Connection conn = getConnection();
conn.setAutoCommit(false);
Statement statement = conn.createStatement();
statement.executeUpdate("update test_tl set addr='abc' where id=1");
conn.commit();
}
private Connection getConnection() throws Exception {
String URL = "jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull";
String NAME = "test";
String PASSWORD = "test";
//1.加載驅動程序
Class.forName("com.mysql.jdbc.Driver");
//2.獲得數據庫的連接
return DriverManager.getConnection(URL, NAME, PASSWORD);
}
}
這么一說大家就都明白了吧。。呵呵。。。。
不過Spring是開源框架所以就復雜了,不過它的里面用到了大量的ThreadLocal來保存上一個DB鏈接。
好了,不多說了。說到這里有興趣的朋友們可以帶着問題去看一下Spring AbstractPlatformTransactionManager這個類的getTransaction方法。