步驟1、在spring配置文件中引入<tx:>命名空間
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
步驟2、xml配置文件中,添加事務管理器bean配置。 java
<!-- 事務管理器配置,單數據源事務 -->
<bean id="pkgouTransactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="pkGouDataSource" />
</bean>
<!-- 使用annotation定義事務 -->
<tx:annotation-driven transaction-manager="pkgouTransactionManager" />
事務註解方式: @Transactionalspring
事務傳播行爲介紹: 數據庫
@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沒有聲明事務,那就不用事務 |
事務超時設置:
@Transactional(timeout=30) //默認是30秒編程
事務隔離級別:數組
@Transactional(isolation = Isolation.READ_UNCOMMITTED) | 讀取未提交數據(會出現髒讀, 不可重複讀) 基本不使用 |
@Transactional(isolation = Isolation.READ_COMMITTED)(SQLSERVER默認) | 讀取已提交數據(會出現不可重複讀和幻讀) |
@Transactional(isolation = Isolation.REPEATABLE_READ) | 可重複讀(會出現幻讀) |
@Transactional(isolation = Isolation.SERIALIZABLE) | 串行化 |
髒讀 : 一個事務讀取到另外一事務未提交的更新數據
不可重複讀 : 在同一事務中, 屢次讀取同一數據返回的結果有所不一樣, 換句話說, 後續讀取能夠讀到另外一事務已提交的更新數據。 相反, "可重複讀"在同一事務中屢次讀取數據時, 可以保證所讀數據同樣, 也就是後續讀取不能讀到另外一事務已提交的更新數據
幻讀 : 一個事務讀到另外一個事務已提交的insert數據網絡
@Transactional的屬性:異步
屬性 | 類型 | 描述 |
---|---|---|
value | String | 可選的限定描述符,指定使用的事務管理器 |
propagation | enum: Propagation | 可選的事務傳播行爲設置 |
isolation | enum: Isolation | 可選的事務隔離級別設置 |
readOnly | boolean | 讀寫或只讀事務,默認讀寫 |
timeout | int (in seconds granularity) | 事務超時時間設置 |
rollbackFor | Class對象數組,必須繼承自Throwable | 致使事務回滾的異常類數組 |
rollbackForClassName | 類名數組,必須繼承自Throwable | 致使事務回滾的異常類名字數組 |
noRollbackFor | Class對象數組,必須繼承自Throwable | 不會致使事務回滾的異常類數組 |
noRollbackForClassName | 類名數組,必須繼承自Throwable | 不會致使事務回滾的異常類名字數組 |
三、 Spring @Transactional的工做原理this
// switch to manual commit if necessary。 this is very expensive in some jdbc drivers,
// so we don't want to do it unnecessarily (for example if we've explicitly
// configured the connection pool to set it already)。if (con。getautocommit())
{
txobject.setmustrestoreautocommit(true);
if (logger.isdebugenabled())
{
logger.debug("switching jdbc connection [" + con + "] to manual commit");
}
con.setautocommit(false);
}
四、 Spring @Transactional的注意事項spa
@Transactional(rollbackFor=Exception.class) //指定回滾,遇到異常Exception時回滾
public void methodName()
{
throw new Exception("註釋");
}
@Transactional(noRollbackFor=Exception.class)//指定不回滾,遇到運行期異常(throw new RuntimeException("註釋");)會回滾
public ItimDaoImpl getItemDaoImpl()
{
throw new RuntimeException("註釋");
}
public void methodName()
{
// 本類的修改方法 1
update();
// 調用其餘類的修改方法
otherBean.update();
// 本類的修改方法 2
update();
}
/*other失敗了不會影響 本類的修改提交成功
本類update的失敗,other也失敗
*/