Spring中的事務處理
數據庫事務(Database Transaction) ,是指作爲單個邏輯工作單元執行的一系列操作,要麼完全地執行,要麼完全地不執行。 事務處理可以確保除非事務性單元內的所有操作都成功完成,否則不會永久更新面向數據的資源。通過將一組相關操作組合爲一個要麼全部成功要麼全部失敗的單元,可以簡化錯誤恢復並使應用程序更加可靠。一個邏輯工作單元要成爲事務,必須滿足所謂的ACID(原子性、一致性、隔離性和持久性)屬性。事務是數據庫運行中的邏輯工作單位,由DBMS中的事務管理子系統負責事務的處理。
xml配置聲明式事務
<!-- 創建事務管理器 -->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="tran">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置事務方法 -->
<tx:advice id="advice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="fun*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 配置AOP -->
<aop:config>
<aop:pointcut expression="execution(* *..service.*.*(..))" id="tx"/>
<aop:advisor advice-ref="advice" pointcut-ref="tx"/>
</aop:config>
開啓註解方式
<!-- 開啓註解方式 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
使用@Transactional添加事務
事務的7種傳播行爲
事務行爲 說明
PROPAGATION_REQUIRED 支持當前事務,假設當前沒有事務,就新建一個事務
PROPAGATION_SUPPORTS 支持當前事務,假設當前沒有事務,就以非事務的方式運行
PROPAGATION_MANDATORY 支持當前事務,若當前沒有事務,否則拋出異常
PROPAGATION_REQUIRES_NEW 新建事務,若當前有事務,則將當前事務掛起
PROPAGATION_NOT_SUPPORTED 以非事務的操作執行,若當前存在事務,則將當前事務掛起
PROPAGATION_NEVER 以非事務的操作執行,若當前存在事務,拋出異常
PROPAGATION_NESTED 若當前存在事務,則在嵌套事務內執行,若當前沒有事務,則新建一個事務
Spring中事務的配置
配置文件的方式
<tx:advice id="advice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="select*" propagation="REQUIRED"/>
<tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="count*" propagation="SUPPORTS" read-only="true"/>
</tx:attributes>
</tx:advice>
註解方式配置
<!-- 開啓註解方式 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
@Transactional(propagation=Propagation.REQUIRED)
//如果有事務, 那麼加入事務, 沒有的話新建一個(默認情況下)
@Transactional(propagation=Propagation.NOT_SUPPORTED)
//容器不爲這個方法開啓事務
@Transactional(propagation=Propagation.REQUIRES_NEW)
//不管是否存在事務,都創建一個新的事務,原來的掛起,新的執行完畢,繼續執行老的事務
@Transactional(propagation=Propagation.MANDATORY)
//必須在一個已有的事務中執行,否則拋出異常
@Transactional(propagation=Propagation.NEVER)
//必須在一個沒有的事務中執行,否則拋出異常(與Propagation.MANDATORY相反)
@Transactional(propagation=Propagation.SUPPORTS)
//如果其他bean調用這個方法,在其他bean中聲明事務,那就用事務.如果其他bean沒有聲明事務,那就不用事務.
事務的隔離界別
Spring中支持的事務隔離級別
隔離級別 描述
DEFAULT 使用數據庫本身的隔離級別,ORACLE(讀已提交)、MySQL(可重複讀)
READ_UNCOMMITED 讀未提交,最低的隔離級別,一切皆有可能
READ_COMMITED 讀已提交,有幻讀和不可重複讀風險
REPEATABLE_READ 可重複讀,有幻讀風險
Spring設置事務的隔離級別
<tx:advice id="advice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT"/>
</tx:attributes>
</tx:advice>
@Transactional(isolation=Isolation.DEFAULT)