8.spring:事務管理(上):Spring的資料庫程式設計、程式設計式事務管理
Spring的資料庫程式設計
Spring框架提供了JDBC模板模式------>JdbcTemplate
簡化了開發,在開發中並不經常是使用
實際開發更多使用的是Hibernate和MyBatis
1).Spring JDBCp配置
如果使用Spring JDBC操作資料庫,要有如下的配置:
在xml配置檔案
<!-- 配置資料來源:可以使用各種資料來源如c3p0.... --> <bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" > <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://127.0.0.1:3306/tx" /> <property name="username" value="root" /> <property name="password" value="1234" /> </bean> <!-- 配置jdbc模組 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean>
配置JDBC模板需要將dataSource注入到jdbcTemplate
有時候也需要將JdbcTemplate注入到相應的Bean中可以使用:
@Autowired
private JdbcTemplate jdbcTemplate ;
2).JdbcTemplate 常用方法
--->public int update(String sql,Object args []):l=可以對資料庫進行增加、修改、刪除等操作...
--->public List<T> query (String sql,RowMapper<T> rowMapper,Object args[]):該方法執行對資料庫的查詢...
相關jar:
-logging
-mysql-connector-java-
-aop
-beans
-context
-core
-expression
-jdbc
tx
注:在dao方法中的操作可以使用@Componment、@Respository、@Service、@controller進行對包掃描,使用@Autowire進行自動注入!
3).測試:
新建資料庫
資料庫對應的實體類:
User.java
public class User { private Integer id; private String name; private String pw; //.... }
tx.xml
<!-- 配置資料來源 --> <bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" > <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://127.0.0.1:3306/tx" /> <property name="username" value="root" /> <property name="password" value="1234" /> </bean> <!-- 配置jdbc模組 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean>
測試:
public ApplicationContext getapp(){ return new ClassPathXmlApplicationContext("tx.xml"); } //增刪改.... @Test public void test1(){ JdbcTemplate jdbcTemplate = (JdbcTemplate) getapp().getBean("jdbcTemplate"); System.out.println(jdbcTemplate); Object a [] = {4,"user4","pwd4"}; Object b [] = {5,"user5","pwd5"}; String sql = "insert into user values(?,?,?)"; //新增使用者 jdbcTemplate.update(sql, a); jdbcTemplate.update(sql, b); //查詢 sql = "select * from user"; RowMapper<User> rowMapper = new BeanPropertyRowMapper<User>(User.class); List<User> users = jdbcTemplate.query(sql, rowMapper, null); for(User user : users){ System.out.println(user); } }
程式設計式事務管理
1).基於底層API的程式設計式事務管理
基於底層API的程式設計式事務管理就是根據PlatformTransactionManager、TransactionDefinition和
TransactionStatus幾個核心介面,通過程式設計的方式解決來進行事務處理。
需要在spring的配置檔案中:
<!-- 配置資料來源 --> <bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" > <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://127.0.0.1:3306/tx" /> <property name="username" value="root" /> <property name="password" value="1234" /> </bean> <!-- 配置jdbc模組 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 為資料來源新增事物管理 --> <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean>
test
//事務管理... @Test public void test2(){ JdbcTemplate jdbcTemplate = (JdbcTemplate) getapp().getBean("jdbcTemplate"); //事物管理器 DataSourceTransactionManager tx = (DataSourceTransactionManager) getapp().getBean("dataSourceTransactionManager"); //預設事物定義,隔離級別、傳播行為.... TransactionDefinition tf = new DefaultTransactionDefinition(); //開啟事物 TransactionStatus ts = tx.getTransaction(tf);
String res = tx(jdbcTemplate, tx, tf, ts); System.out.println(res); } public String tx(JdbcTemplate jdbcTemplate,DataSourceTransactionManager tx, TransactionDefinition tf,TransactionStatus ts){ String msg = "執行成功,沒有事物回滾!"; try{ Object a [] = {2,"user2","pwd2"}; String sql = "insert into user values(?,?,?)"; //新增使用者 //主鍵重複 jdbcTemplate.update(sql, a); //提交事務 tx.commit(ts); }catch(Exception e){ //出現異常,事物回滾 tx.rollback(ts); msg= "主鍵重複!!!"; e.printStackTrace(); } return msg; }
以上的這種操作會讓事物處理的程式碼散落在業務邏輯程式碼中,破壞了原有程式碼的條理性,並且讓每一個業務方法都包含了
類似啟動事物、提交以及回滾事務的樣板式程式碼。
TransactionTemplate的execute方法有一個TransactionCallback介面型別的引數,該介面定義了doInTransaction方法、通常
以匿名內部類的方式實現TransactionCallback介面,在doInTransaction方法中寫業務邏輯程式碼
public T doInTransaction(TransactionStatus arg0)
TransactionStatus型別引數、可以在方法的任何位置呼叫該引數方法的setRollbackOnly方法將事務標識為回滾、以執行事務回滾
根據預設規則:
如果在執行回撥方法過程中如果丟擲未檢查異常或者顯示呼叫setRollbackOnly方法,則回滾事物
如果事務執行完成或丟擲了checked型別的異常,則提交事務
程式碼待完成......