springMVC已經愈來愈流行了。如下是對spring事務的一些我的總結。咱們先了解下事務:數據庫事務(Database Transaction) ,是指做爲單個邏輯工做單元執行的一系列操做。 事務處理能夠確保除非事務性單元內的全部操做都成功完成,不然不會永久更新面向數據的資源。經過將一組相關操做組合爲一個要麼所有成功要麼所有失敗的單元,能夠簡化錯誤恢復並使應用程序更加可靠。一個邏輯工做單元要成爲事務,必須知足所謂的ACID(原子性、一致性、隔離性和持久性)屬性。spring
那麼在spring框架中怎麼使用尼?sql
一、dataSource,jdbcTemplate配置(默認已經瞭解spring)數據庫
<!-- 配置jdbcTemplate --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 配置數據源 --> <!-- 以dataSource方式使用proxool鏈接池 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" init-method="init" destroy-method="close"> <property name="name" value="${jdbc.username}" /> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="initialSize" value="${ds.initialSize}" /> <property name="minIdle" value="${ds.minIdle}" /> <property name="maxActive" value="${ds.maxActive}" /> <property name="maxWait" value="${ds.maxWait}" /> <property name="timeBetweenEvictionRunsMillis" value="${ds.timeBetweenEvictionRunsMillis}" /> <property name="validationQuery" value="SELECT 'x' FROM dual" /> <property name="connectionProperties" value="oracle.jdbc.ReadTimeout=${oracle.jdbc.ReadTimeout};oracle.net.CONNECT_TIMEOUT=${oracle.net.CONNECT_TIMEOUT}" /> </bean>
爲了方便修改,採起配置文件的形式。oracle
# 數據庫類型設置(oracle) ds.dialect=oracle # Oracle數據庫 jdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:orcl jdbc.driver=oracle.jdbc.driver.OracleDriver jdbc.username=dreamer jdbc.password=123qwe # SQL執行時間超過必定時間則記錄爲慢SQL ds.slowSqlMillis=3000 # 慢SQL統計日誌輸出 ds.logSlowSql=false # 合併SQL統計 ds.mergeSql=false # 初始化時創建物理鏈接的個數 ds.initialSize=1 # 最小鏈接數 ds.minIdle=1 # 容許最大鏈接數,超過了這個鏈接,再有請求時,就排在隊列中等候,最大的等待請求數由maximum-new-connections決定 ds.maxActive=20 # 獲取鏈接時最大等待時間 ds.maxWait=5000 # 檢測須要關閉的空閒鏈接的間隔時間, 單位是毫秒 ds.timeBetweenEvictionRunsMillis=120000 #oracle jdbc驅動socket超時 oracle.jdbc.ReadTimeout=600000 #oracle jdbc創建新鏈接超時時間 oracle.net.CONNECT_TIMEOUT=6000
而後就是若是簡單的操做數據庫了。示例代碼app
public class JdbcDemo { @Autowired public JdbcTemplate jdbcTemplate; public void callP(){ //調用存儲過程 jdbcTemplate.execute("{}", new CallableStatementCallback<String>() { @Override public String doInCallableStatement(CallableStatement stat) throws SQLException, DataAccessException { //填參數 stat.setString(0, "hello"); ResultSet rs = stat.executeQuery(); while( rs.next()){ rs.getString(0); //....取值 } return null; } }); } public void query(){ //查詢 jdbcTemplate.query("sql", new RowMapper<Object>(){ @Override public Object mapRow(ResultSet rs, int arg1) throws SQLException { rs.getString(0); //..... return null; }}); } }
上面就是spring操做數據庫了。此時就涉及到事務管理。若是使用spring事務管理尼。咱們能夠經過依賴注入@Transactional來使用提醒兩個注意點:框架
1.只有經過spring方式實例化纔有事務。經過new方式實例化將不包含事務
2.當調用的第一個方法有事務時,裏面調用的其餘方法也將包含在同一事務裏面,反之若是第一個方法沒有配置事務,方法內部平級調用方法(此方法配置了事務)。事務也將無效。socket
public class Test { @Transactional public void delData(){ //有事務 delTabA(); //自己配置事務無效,事務類型與delData()一致 delTabB(); } public void delTabA(){ } @Transactional(propagation=Propagation.REQUIRES_NEW) public void delTabB(){ } } class TestDemo{ @Autowired private Test test; public void test() { //有事務 test.delData(); Test test2 = new Test(); //無事務 test2.delData(); } }
3.當方法中拋出異常時,若是聲明瞭拋出異常,事務是不回滾的。若是拋出異常時未檢查的。事務將會回滾。
若是須要回滾須要增長配置@Transactional(rollbackFor=Exception.class)指定異常,可同時配置多個異常ide
import org.springframework.transaction.annotation.Transactional; public class Test2 { //出現異常將不會回滾 @Transactional public void test ()throws Exception{ throw new Exception(); } //將會回滾 @Transactional(rollbackFor=Exception.class) public void test2()throws Exception{ throw new Exception(); } //將會回滾 @Transactional public void test3(){ throw new RuntimeException("例外"); } }
經過依賴注入能夠選着注入的事務類型 @Transactional(propagation=Propagation.REQUIRES_NEW)url
PROPAGATION_REQUIRED:支持當前事務,若是當前沒有事務,就新建一個事務。這是最多見的選擇。
PROPAGATION_SUPPORTS:支持當前事務,若是當前沒有事務,就以非事務方式執行。
PROPAGATION_MANDATORY:支持當前事務,若是當前沒有事務,就拋出異常。
PROPAGATION_REQUIRES_NEW:新建事務,若是當前存在事務,把當前事務掛起。
PROPAGATION_NOT_SUPPORTED:以非事務方式執行操做,若是當前存在事務,就把當前事務掛起。
PROPAGATION_NEVER:以非事務方式執行,若是當前存在事務,則拋出異常。
PROPAGATION_NESTED:支持當前事務,若是當前事務存在,則執行一個嵌套事務,若是當前沒有事務,就新建一個事務。
上面就是對單個方法進行事務控制。適合須要精細化處理的項目。但但部分項目不須要這麼精細。就能夠經過配置對某個包下方法進行IOC事務配置。spa