在上一篇文章裏面寫了關於事務的一些特性,這裏在談談事務的編程模型。什麼叫作事務的編程模型,這個問題比較難以回答,其實簡單的一句話,就是咱們如何去使用和控制事務。在java平臺裏面,有三種事務編程模型:本地事務模型,編程式事務模型,聲明式事務模型(固然我不是太認同這種說法,並非太準確,不過大致也就這麼回事情)java
本地事務模型:不用事務的編程框架來管理事務,直接使用資源管理器來控制事務。典型的就是java.sql.Connection 中的 setAutoCommit、commit、rollback方法,見下面一段代碼,直接使用資源管理器進行事務控制spring
Connection conn = getConnection(); conn.setAutoCommit(false); // do something boolean success = doSomething(); if (success) { conn.commit(); } else { conn.rollback(); }
編程式事務模型:就是使用java提供的事務api JTA(Java Transaction API)sql
和事務服務提供者(通常是指j2ee容器) 進行事務控制,JTA裏面提供了 java.transaction.UserTransaction ,裏面定義了下面幾個方法數據庫
begin:開啓一個事務編程
commit:提交當前事務api
rollback:回滾當前事務服務器
setRollbackOnly:把當前事務標記爲回滾框架
setTransactionTimeout:設置事務的事件,超過這個事件,就拋出異常,回滾事務分佈式
getStatus;ide
不過JTA只是提供了一個接口,並無提供具體的實現,而是由j2ee服務器提供商 根據JTS規範提供的。下面一段代碼演示瞭如何使用事務JPA
InitialContext ctx = new InitialContext(); UserTransaction ut = (UserTransaction) ctx.lookup("javax.transaction.UserTransaction"); ut.begin(); //do something boolean isSuccess = doSomething() ; if(isSuccess){ ut.commit(); }else{ ut.rollback(); }
JPA規範裏面定義了事務相關的幾個角色:事務上下文,資源管理器,通訊管理器,應用程序,事務管理器,事務服務提供者。其中資源管理器主要就是咱們常見的數據庫鏈接和JMS鏈接,事務上下文這裏能夠理解爲事務的狀態和屬性信息,應用程序就是使用事務服務的程序,事務服務提供者就是實現了jta規範的j2ee容器。事務管理器就是應用程序和事務服務提供者的api接口。通訊管理器主要是用在分佈式事務裏面。
這個是java裏面JPA的規範,可是也有一些編程框架提供了本身的編程事務模型,例如java裏最經常使用的就是spring的事務管理器,下面是spring提供的編程接口:org.springframework.transaction.PlatformTransactionManager,這裏面就只有三個方法:
getTransaction:根據屬性信息決定是否開啓事務(具體能夠看上一篇文章裏面的事務特性小結裏面的事務傳播屬性)
commit;提交當前事務
rollback;回滾當前事務
咱們發現其實和JPA提供的編程模型很像,就是開啓一個事務,提交仍是回滾事務。spring提供的事務編程框架也比較簡單
ApplicationContext context = getApplicationContext(); TransactionTemplate transactionTemplate = (TransactionTemplate)context.getBean("TransactionTemplate"); transactionTemplate.execute(new TransactionCallback() { public Object doInTransaction(TransactionStatus status) { boolean isSuccess = doSomething() ; if(isSuccess){ }else{ status.setRollbackOnly(); } return isSuccess; } });
聲明式編程:這種編程模型不採用硬編碼的方式,而是採用在xml裏面進行配置的方式或者使用anotation的方式進行。例如srping裏面能夠經過aop進行實現
<bean id="accountService" class="org.springframework.transaction.interceptor. TransactionProxyFactoryBean"> <property name="transactionManager" ref="transactionManager"/> <property name="target" ref="accountServiceTarget"/> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_SUPPORTS</prop> <prop key="update*">PROPAGATION_REQUIRED </prop> </props> </property>
以上三種編程模型,第一種比較簡單,也只是適合控制單個資源事務,若是涉及到跨資源(好比兩個數據庫鏈接之間)事務控制,就無能爲力了,也就是說不可以提供分佈式事務的解決方案, 而JPA提供了分佈式事務的解決方案,這一塊之前瞭解過,後來忘記了,準備在溫習一下,在整理和總結如下。而spring提供的編程事務模型,則是在局部事務和JPA事務的基礎上提供了一層封裝,統一了二者的編程模型,也就是說spring其實也提供JPA的編程接口,也就是 JtaTransactionManager,只不過具體實現 委託給jta provider而已。因此基本上編程模型這個劃分仍是比較模糊的,直接使用spring提供的編程模型便可。