MyBatis 事务源码分析
先來看看在JAVA事務(wù)的相關(guān)技術(shù),在JAVA中有兩類事務(wù),JDBC事務(wù)和JTA事務(wù),如果是JDBC類型的事務(wù),則是由Connection類來控制的。如果創(chuàng)建一個Connection對象時,沒有顯示調(diào)用
setTransactionIsolation(int?level)?方法,則Connection使用當(dāng)前數(shù)據(jù)庫默認(rèn)的事務(wù)隔離級別,數(shù)據(jù)庫的默認(rèn)事務(wù)隔離級別可以通過相應(yīng)的SQL語句進行查詢,例如在Mysql數(shù)據(jù)庫下可使用?select?@@tx_isolation;語句查看當(dāng)前數(shù)據(jù)庫的事務(wù)隔離級別。
JDBC的Connection類針對事務(wù)的隔離性定義了五個隔離級別。
Connection.TRANSACTION_NONE
Connection.TRANSACTION_READ_COMMITTED
Connection.TRANSACTION_READ_UNCOMMITTED
Connection.TRANSACTION_REPEATABLE_READ
Connection.TRANSACTION_SERIALIZABLE
在mybatis中,有一個事務(wù)管理器的配置,其中type屬性可以配置事務(wù)的類型,提供了JDBC或MANAGED的配置屬性,這就說明在mybatis中事務(wù)的管理方式有兩個事務(wù)管理器的實現(xiàn),都是針對JDBC事務(wù)的事務(wù)管理器(非JTA事務(wù)),分別是:
??org.apache.ibatis.transaction.jdbc.JdbcTransaction
??org.apache.ibatis.transaction.managed.ManagedTransaction
這兩個類都實現(xiàn)了org.apache.ibatis.transaction.Transaction接口,Transaction接口定義了如下方法:
Connection getConnection() throws SQLException;void commit() throws SQLException; void rollback() throws SQLException; void close() throws SQLException;通過這些方法可以看出這個接口實際是對Connection類進行了包裝,包括了Connection的創(chuàng)建、提交、回滾、關(guān)閉動作。并且,其中ManagedTransaction類的commit方法和rollback方法中沒有做任何事,也就是說這個類是不控制事務(wù)的提交和回滾的,而交由外部容器去管理事務(wù)的提交與回滾,外部容器(可以是Spring?容器或EJB容器)通過聲明式事務(wù)的方式進行管事。
在mybatis中,通過一個Enum類org.apache.ibatis.session.TransactionIsolationLevel
來定義了事務(wù)的隔離級別:
public enum TransactionIsolationLevel {NONE(Connection.TRANSACTION_NONE),READ_COMMITTED(Connection.TRANSACTION_READ_COMMITTED),READ_UNCOMMITTED(Connection.TRANSACTION_READ_UNCOMMITTED),REPEATABLE_READ(Connection.TRANSACTION_REPEATABLE_READ),SERIALIZABLE(Connection.TRANSACTION_SERIALIZABLE);private final int level; private TransactionIsolationLevel(int level) { this.level = level; } public int getLevel() { return level; } }TransactionIsolationLevel類中定義的事務(wù)隔離級別其實就是引用了Connection類中的事務(wù)隔離級別,下面分別對這幾種隔離級別進行說明:?
TRANSACTION_NONE:表示不支持事務(wù)的常量
TRANSACTION_READ_UNCOMMITTED:表示可以發(fā)生臟讀?(dirty?read)、不可重復(fù)讀和虛讀?(phantom?read)?的常量
TRANSACTION_READ_COMMITTED:不可重復(fù)讀和虛讀可以發(fā)生
TRANSACTION_REPEATABLE_READ:虛讀可以發(fā)生
TRANSACTION_SERIALIZABLE:指示不可以發(fā)生臟讀、不可重復(fù)讀和虛讀的常量。
再來理解下什么是臟讀、不能重復(fù)讀、虛讀(又叫幻讀)
臟讀:如果一個事務(wù)對數(shù)據(jù)進行了更新,但事務(wù)還沒有提交,另一個事務(wù)就可以“看到”該事務(wù)沒有提交的更新結(jié)果。這樣造成的問題是,如果第一個事務(wù)回滾,那么第二個事務(wù)在此之前所“看到”的數(shù)據(jù)就是一筆臟數(shù)據(jù)。
不可重復(fù)讀:指同個事務(wù)在整個事務(wù)過程中對同一筆數(shù)據(jù)進行讀取,每次讀取結(jié)果都不同。如果事務(wù)1在事務(wù)2的更新操作之前讀取一次數(shù)據(jù),在事務(wù)2的更新操作之后再讀取同一筆數(shù)據(jù)一次,兩次結(jié)果是不同的。所以TRANSACTION_READ_COMMITTED是無法避免不可重復(fù)讀和虛讀。
幻讀:指同樣一個查詢在整個事務(wù)過程中多次執(zhí)行后,查詢所得的結(jié)果集是不一樣的。幻讀針對的是多筆記錄。
最后再總結(jié)下:mybatis只是對JDBC事務(wù)提供了事務(wù)管理器的封裝,如果想在mybatis中使用JTA事務(wù),需要我們自行實現(xiàn)org.apache.ibatis.transaction.Transaction接口,對此Spring框架提供了解決方案,可能通過mybatis+spring+atomikos的整合來完成。或者采用EJB容器也可以提供JTA事務(wù)的支持。
轉(zhuǎn)載于:https://www.cnblogs.com/wl0000-03/p/6443900.html
總結(jié)
以上是生活随笔為你收集整理的MyBatis 事务源码分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Codeforces Round #40
- 下一篇: 我国油气领域获重大突破:“地下珠峰”已找