9.spring:事務管理(下):宣告式事務管理
宣告式事務管理
sprin的宣告式事務是管理AOP技術實現的事務管理,其本質是是對方法前後進行攔截,然後
在目標方法開始之前建立或者加入一個事務,在執行完成目標方法之後根據執行情況提交或者回滾事務。
宣告式事務管理優點:不需要通過程式設計的方式管理事務,因而不需要在業務邏輯程式碼中摻雜事務處理的程式碼,
只需相關的事務規則宣告便可以將事務規則應用到業務邏輯中。
在開發中使用宣告式事務處理不僅因為其簡單,更主要是這樣可以使純業務程式碼不被汙染,方便後期的維護。
宣告式事務管理不足之處:是最細粒純度只能作用到方法級別,無法做到像程式設計事務管理
spring的宣告式事務管理可以通過兩種方式實現:1、xml配置方式 2、使用@Transactionl註解方式
1).xml配置方式
public interface TestDao { public int save(String sql,Object p []); public int delete(String sql,Object p []); }
@Repository("TestDao") public class TestDaoImpl implements TestDao{ @Autowiredprivate JdbcTemplate jdbcTemplate ; @Override public int save(String sql, Object[] p) { return jdbcTemplate.update(sql, p); } @Override public int delete(String sql, Object[] p) { // TODO Auto-generated method stub return jdbcTemplate.update(sql, p); } }
public interface TestService { public int save(String sql,Object p []); public int delete(String sql,Object p []); }
@Service("TestService") public class TestServiceImpl implements TestService{ @Autowired private TestDao testDao ; @Override public int save(String sql, Object[] p) { return testDao.save(sql, p); } @Override public int delete(String sql, Object[] p) { // TODO Auto-generated method stub return testDao.delete(sql, p); } }
spring配置檔案
<!--掃描指定的包--> <context:component-scan base-package="com.MrChegnse.jdbctest"></context:component-scan> <!-- 配置資料來源 --> <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> <!-- 編寫宣告式事物 --> <!-- transaction-manager:DataSourceTransactionManager類的例項化 --> <tx:advice id="myAdvice" transaction-manager="dataSourceTransactionManager"> <tx:attributes>
<!-- * 表示任意的方法 --> <tx:method name="*"/> </tx:attributes> </tx:advice> <!-- 編寫AOP讓spring自動對目標生成代理 --> <aop:config> <!-- 定義切點 --> <aop:pointcut expression="execution(* com.MrChegnse.jdbctest.*.*())" id="point"/> <!-- 切面:將切入點與通知關聯 --> <aop:advisor advice-ref="myAdvice" pointcut-ref="point"/> </aop:config>
測試
public ApplicationContext getapp(){ return new ClassPathXmlApplicationContext("tx.xml"); }
public String test11(){
TestService testService = (TestService) getapp().getBean("testService");
String msg2 = "";
Object a [] = {2,"user2","pwd2"};
String sql = "insert into user values(?,?,?)";
try {
testService.save(sql, a);
} catch (Exception e) {
msg2 ="error";
e.printStackTrace();
}
return msg2;
}
@Test
public void test22(){
String a = test11();
System.out.println(a);
}
注:
1、<tx:advice>配置事務的通知
2、<tx:advice>一般需要指定id和transaction-manager屬性,id是在配置檔案中唯一標識,transaction-manager指定事務管理器
3、<tx:attributes>是<tx:advice>的子元素、執行執行事務的細節
4、<tx:advice>配置了事務增強處理後就可通過AOP配置讓spring自動對目標生成代理
5、<aop:pointcut expression="execution(* com.MrChegnse.jdbctest.*.*())" id="point"/>
*:代表任意型別、任意類、任意方法
6、<aop:advisor advice-ref="myAdvice" pointcut-ref="point"/>:將切入點與通知關聯
2)@Transactionl註解宣告式事務管理
public interface TestDao { public int save(String sql,Object p []); public int delete(String sql,Object p []); }
@Repository("TestDao") public class TestDaoImpl implements TestDao{ @Autowired private JdbcTemplate jdbcTemplate ; @Override public int save(String sql, Object[] p) { return jdbcTemplate.update(sql, p); } @Override public int delete(String sql, Object[] p) { // TODO Auto-generated method stub return jdbcTemplate.update(sql, p); } }
public interface TestService { public int save(String sql,Object p []); public int delete(String sql,Object p []); }
@Service("TestService") @Transactional public class TestServiceImpl implements TestService{ @Autowired private TestDao testDao ; @Override public int save(String sql, Object[] p) { return testDao.save(sql, p); } @Override public int delete(String sql, Object[] p) { // TODO Auto-generated method stub return testDao.delete(sql, p); } }
spring的配置檔案
<context:component-scan base-package="com.MrChegnse.jdbctest"></context:component-scan> <!-- 配置資料來源 --> <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> <!-- 為事務管理器註冊註解驅動 --> <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
測試
public String test11(){ TestService testService = (TestService) getapp().getBean("testService"); String msg2 = ""; Object a [] = {2,"user2","pwd2"}; String sql = "insert into user values(?,?,?)"; try { testService.save(sql, a); } catch (Exception e) { msg2 ="error"; e.printStackTrace(); } return msg2; } @Test public void test22(){ String a = test11(); System.out.println(a); }
注:
1、@Transactional:可以作用於介面、介面方法、類以及類的方法
2、當作用於類上時,該類的所有public方法都將具有該型別的事務屬性,同時也可以在方法級別使用該註解來覆蓋類級別的定義
3、Spring小組建議不要在介面或者方法上使用該註解,因為他只有在使用基於介面的代理時才會生效。
4、@Transactional(rollbackFor=RuntimeException.class):不對RuntimeException回滾生效
5、@Transactional(rollbackFor=Exception.class):不對Exception回滾生效
6、<tx:annotation-driven />:為事務管理器註冊註解驅動驅動器
7、 @Transactional
public class TestServiceImpl implements TestService{
加上註解就可以指定這個類需要接受Spring的事務管理
只能針對public屬性範圍內的方法新增
基本完結..........