事务的实现
2019獨角獸企業(yè)重金招聘Python工程師標準>>>
事務的本質:讓程序像我們看到的那樣執(zhí)行。
? ? 數據庫事務就是對于界定為同一個事務的一組數據庫操作,要么同時成功,要么同時失敗,不可能出現部分成功的中間狀態(tài)。
? ? 對于JDBC原生事務,首先要設置自動提交為false:connection.setAutoCommit(false),如果整個執(zhí)行過程沒有異常則提交事務commit,否則就回滾rollback。對于原生態(tài)的jdbc事務,編碼顯得非常繁瑣,并且對于整個系統(tǒng)的共性業(yè)務,特別適合用AOP的方式來實現。
? ? 下面說到重點了,TeaFramework事務實現。
? ? 1、事務的使用應該盡量簡單,在方法或者class上加一個注解便可搞定,對于class有事務注解,那么該class所有方法都有進行事務控制。
@Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) public @interface Transcation { }? ? 2、事務的傳播
? ? 事務的傳播描述的是多個事務嵌套的問題,對于大部分場景而言,頂層方法有事務,則子事務被納入當前事務,這種場景占80%,那么TeaFramework只實現這種事務傳播。
? ? 請看具體的代碼
public class TranscationProxy extends AbstractProxy {private Logger logger = LoggerFactory.getLogger(getClass());@Overridepublic void invoke(Proxy proxy) throws Throwable {BeanProxy beanProxy = (BeanProxy) proxy;boolean classHasTranscationAnnotation = beanProxy.getObj().getClass().getSuperclass().isAnnotationPresent(Transcation.class);boolean methodHasTranscationAnnotation = beanProxy.getMethod().isAnnotationPresent(Transcation.class);if (TranscationThreadVariable.get() == null&& (classHasTranscationAnnotation || methodHasTranscationAnnotation)) {// 如果類或者方法有Transcation注解則進入try {before(proxy);proxy.invoke(proxy);after(proxy);} catch (Throwable e) {exception(proxy);throw e;} finally {end(beanProxy);}} else {proxy.invoke(proxy);}}@Overridepublic void before(Proxy proxy) {try {TranscationThreadVariable.set(true);logger.debug("開啟事務");if (ConnectionThreadVariable.getConnetion() == null) {Connection connection = DataSourceHelp.getConnection();connection.setAutoCommit(false);ConnectionThreadVariable.setConnetion(connection);}} catch (Exception e) {throw new TranscationException(e);}}@Overridepublic void after(Proxy proxy) {try {logger.debug("提交事務");ConnectionThreadVariable.getConnetion().commit();} catch (Exception e) {throw new TranscationException(e);}}@Overridepublic void exception(Proxy proxy) {try {logger.debug("回滾事務");ConnectionThreadVariable.getConnetion().rollback();} catch (Exception e) {throw new TranscationException(e);}}@Overridepublic void end(Proxy proxy) {try {logger.debug("關閉連接");ConnectionThreadVariable.getConnetion().close();} catch (Exception e) {throw new TranscationException(e);} finally {ConnectionThreadVariable.clearThreadVariable();TranscationThreadVariable.clearThreadVariable();}}}? ? 這里本質上是實現了一個代理類,用AOP的思路來實現
? ? 1、before:在事務開啟之前,獲取數據庫連接,并設置自動提交為false
? ? 2、after:執(zhí)行過程如果沒有任何異常,則提交事務
? ? 3、exception:執(zhí)行過程發(fā)生異常,則回滾事務
? ? 4、end:執(zhí)行結束,關閉數據庫連接,歸還給連接池
? ? 那么事務的傳播在哪里實現的呢?僅僅只有一行代碼TranscationThreadVariable.set(true),這行代碼標示了當前線程中事務的狀態(tài),如果事務已經由上層方法開啟,則下面所有的數據庫操作與開啟事務的方法共用一個數據庫連接connection,那么就被納入了一個事務。
? ? 來看一個例子,在insert方法上加上@Transcation注解
@TeaDao("testDao") public interface TestDao {@Transcation@GetPrimaryKey(sql = "select s_users.nextval from dual", primaryKeyProperty = "id")@SQL("insert into users(id,name,password,createdate) values(#id#,#name#,#password#,#createdate#)")public int add(Map<String, Object> map);@DynamicSQLpublic int update();@SQL("delete from users")public int deleteUserById();@SQL("select * from users")public List<User> getAllUser();@DynamicSQLpublic List<User> findUser();}? ? 執(zhí)行結果:
? ? 這就是TeaFramework事務的實現過程。
轉載于:https://my.oschina.net/architectliuyuanyuan/blog/1611442
總結
- 上一篇: 对GC垃圾收集的一点整理
- 下一篇: Hive JDBC:Permission