我覺得自己寫的不好,所以先貼一個寫的好的帖子 感覺看完不用回來了。。。。 這是一個大佬寫的的博客 : https://www.cnblogs.com/yixianyixian/p/8372832.html 第一:JavaEE 體系進行分層開發,事務處理位於業務層,Spring 提供了分層設計 業務層 ...
我覺得自己寫的不好,所以先貼一個寫的好的帖子
感覺看完不用回來了。。。。
這是一個大佬寫的的博客 : https://www.cnblogs.com/yixianyixian/p/8372832.html
第一:JavaEE 體系進行分層開發,事務處理位於業務層,Spring 提供了分層設計業務層的事務處理解決方
案。
第二:spring 框架為我們提供了一組事務控制的介面。具體在後面的第二小節介紹。這組介面是在
spring-tx-5.0.2.RELEASE.jar 中。
第三:spring 的事務控制都是基於 AOP 的,它既可以使用編程的方式實現,也可以使用配置的方式實現。我
們學習的重點是使用配置的方式實現。
API 介紹
PlatformTransationManager
Spring提供了一個事務管理器介面PlatformTransationManager
,該介面包含了三個方法:
- getTransation()//提交事務
- commit();//提交事務
- rollback();//回滾事務
在開發中,根據應用的技術不同,使用不同的實現類
SpringJDBC / iBatis:org.springframework.jdbc.datasource.DataSourceTransactionManager
Hibernate:org.springframework.orm.hibernate5.HibernateTransactionManager
TransactionManager
Transactionmanager
是事務信息對象,定義了與事務信息相關的方法
獲取事務對象名稱
String getName()
獲取事務隔離級別
int getIsolationLevel()
獲取事務傳播行為
int getPropagationBehavior()
獲取事務超時時間
getTimeOut()
獲取事務是否為只讀
IsReadOnly()
TransactionManager的隔離級別和傳播行為有固定的參數
隔離級別
ISOLATION_DEFAULT ---(資料庫)預設基本
ISOLATION_READ_UNCOMMITTED ---可讀取未提交的數據
ISOLATION_READ_COMMITTED --- 只能讀取已提交的數據(oracle預設級別)
ISOLATION_REPEATABLE_READ --- 是否讀取其他事務提交修改後的數據,解決不可重覆讀的問題(mysql預設級別)
ISOLATION_SERIALIZABLE --- 是否讀取其他事務提交添加後的數據,解決幻影讀問題
事務傳播行為
REQUIRED:如果當前沒有事務,就新建一個事務,如果已經存在一個事務中,加入到這個事務中。一般的選
擇(預設值)
SUPPORTS:支持當前事務,如果當前沒有事務,就以非事務方式執行(沒有事務)
MANDATORY:使用當前的事務,如果當前沒有事務,就拋出異常
REQUERS_NEW:新建事務,如果當前在事務中,把當前事務掛起。
NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起
NEVER:以非事務方式運行,如果當前存在事務,拋出異常
NESTED:如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則執行 REQUIRED 類似的操作。
事務超時時間:預設-1
沒有時間限制,以秒為單位
TransationStatus
這個介面提供了事務的運行狀態
flush();刷新事務
hasSavepoint();是否在存儲點
isCompleted();是否完成
isNewTransaction();是否是新事務
isRollbackOnly();是否回滾事務
setRollbackOnly();設置事務回滾
基於XML的配置
首先最基本幾件事:導入jar包/坐標,導入(xml)約束
spring-jdbc包,spring-tx包,aspectjweaver
如果需要測試,需要加上junit-4.12,spring-test
約束
這個可以在文檔里找到
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
DAO
真正與資料庫交互的層
在準備dao之前應準備表的實體類[略]
dao層的介面,只寫連個,其他的方法都類似
public interface IDeptDao {
List<Dept> findAll(Integer id);
void Update(Dept dept);
}
實現類繼承JdbcDaoSupport
,減少代碼冗餘
public class DeptDaoImpl extends JdbcDaoSupport implements IDeptDao {
public List<Dept> findAll(Integer id) {
return null;
}
public void Update(Dept dept) {
int update = getJdbcTemplate().update("update dept set deptno= ? where dname = 'a' ",dept.getDeptno());
System.out.println("更改後----"+update);
}
}
Service層
根據DAO層,準備Service層的介面
與實現類
介面
public interface IDeptSer {
List<Dept> findAll(Integer id);
void Update(Dept dept);
}
這裡的實現類
直接調用對應的方法
public class DeptSerImpl implements IDeptSer {
private DeptDaoImpl deptDao;
public void setDeptDao(DeptDaoImpl deptDao) {
this.deptDao = deptDao;
}
public List<Dept> findAll(Integer id) {
return deptDao.findAll(id);
}
public void Update(Dept dept) {
deptDao.Update(dept);
dept.setDeptno(80);
// int k = 0/0;//手動製造異常
deptDao.Update(dept);
}
}
xml配置
與資料庫交互的寫好了,現在就是配置了
配置數據源
<!--數據源-->
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///test"></property>
<property name="username" value="root"></property>
<property name="password" value="1234"></property>
</bean>
配置dao
層和service
層
<!--dao層實現類-->
<bean id="deptDao" class="gx.dao.impl.DeptDaoImpl">
<property name="dataSource" ref="datasource"></property>
</bean>
<!--service層實現類-->
<bean id="ds" class="gx.ser.impl.DeptSerImpl">
<property name="deptDao" ref="deptDao"></property>
</bean>
事務管理
終於到了重點了
配置時間到
配置步驟
-
配置事務管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="datasource"></property> </bean>
-
配置事務管理器的通知引用事務管理器
-
配置事務的屬性
<!--第二步--> <tx:advice id="txAdcvice" transaction-manager="transactionManager"> <!--第三步--> <tx:attributes> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice>
-
配置AOP切入點表達式
-
配置切入點表達式和事務通知的對應關係
<aop:config>
<!--第四步-->
<aop:pointcut id="pt1" expression="execution(* gx.ser.impl.*.*(..))"/>
<!--第五步-->
<aop:advisor advice-ref="txAdcvice" pointcut-ref="pt1"></aop:advisor>
</aop:config>
屬性:name --- 方法名稱
可用 通配符* 例:
匹配所有find開頭的方法:find*(優先順序高)
匹配所有方法:*
其他屬性
指定方法名稱:是業務核心方法
read-only:是否是只讀事務。預設 false,不只讀。
isolation:指定事務的隔離級別。預設值是使用資料庫的預設隔離級別。
propagation:指定事務的傳播行為。
timeout:指定超時時間。預設值為:-1。永不超時。
rollback-for:用於指定一個異常,當執行產生該異常時,事務回滾。產生其他異常,事務不回滾。
沒有預設值,任何異常都回滾。