注意有一點 : service層在調用的時候也就是事物管理的那個方法裏不能用try{}catch(){} , 若是用了 ,異常被捕獲了 , 事物管理就發現不了異常 ,也就不會進行回滾 java
還有個spring的動態代理提一下mysql
spring的動態的代理模式有兩種spring
JDK動態代理,基於接口(默認代理模式),CGLIB動態代理(若要使用須要進行配置)1.使用aop配置:
<aop:config proxy-target-class="false"> </aop:config>
2. aspectj配置:
<aop:aspectj-autoproxy proxy-target-class="true"/>
3. 事務annotation配置:
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
sql
3種配置,只要使用一種便可,設置proxy-target-class爲true即便用cglib的方式代理對象。數據庫
DK動態代理和CGLIB動態代理的區別?express
(1)JDK動態代理只能對實現了接口的類生成代理,而不能針對類
(2)CGLIB是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的方法
由於是繼承,因此該類或方法最好不要聲明成finalapp
簡單來講就是 ,spring默認jdk動態代理 , 而後getBean的時候只能取接口 ,和返回接口類型ide
而cglib動態代理時 ,getBean裏能夠是實現類 ,也能夠是接口 . 測試
數據庫的事物呢 , 就是指做爲單個邏輯工做單元執行的一系列操做,要麼徹底地執行,要麼徹底地不執行。this
事務處理能夠確保除非事務性單元內的全部操做都成功完成,不然不會永久更新面向數據的資源。
實現事物管理的方式也有xml的配置方式和註解的方式
xml的方式步驟:
寫個對應數據庫表的javaBean
public class User { private int id; private String name; private int age;
寫出數據操做的dao層
public class UserDao { private JdbcTemplate template; public void setTemplate(JdbcTemplate template) { this.template = template; } public void add(){ String sql = "insert into user(name,password,age)values(?,?,?)"; int count = template.update(sql , "1112","afjaof",20); System.out.println("影響的行數:"+count); } public void update(){ String sql = "update user set age1=? where id=?"; int count = template.update(sql,33,17); System.out.println("影響的行數:"+count); } public void delete(){ String sql = "delete from user where id = ?"; template.update(sql, 34); } public void query1(){ String sql = "select * from user"; List<User> list = template.query(sql, new RowMapper<User>(){ @Override public User mapRow(ResultSet rs, int rowNum) throws SQLException { System.out.println(rowNum); User user = new User(); user.setId(rs.getInt("id")); user.setName(rs.getString("name")); user.setAge(rs.getInt("age")); return user; } }); for (User user : list) { System.out.println(user); } } public void query2(){ String sql = "select * from t_user"; List<User> list = template.query(sql, new BeanPropertyRowMapper(User.class)); for (User user : list) { System.out.println(user); } } }
而後是service層
@Component public class UserServiceImpl implements UserService { @Resource private UserDao dao; @Override public void fun1() { dao.add(); dao.update(); } }
xml配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <context:component-scan base-package="com.sxt.*,com.liy.*"></context:component-scan> <bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate"> <!-- 構造注入關聯數據源 --> <constructor-arg name="dataSource" ref="dataSource"/> </bean> <!-- 配置數據源 --> <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource"> <!-- 配置數據庫的相關信息 --> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/again?characterEncoding=utf-8"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean> <!-- 配置UserDao --> <bean class="com.sxt.dao.UserDao"> <property name="template" ref="jdbcTemplate" /> </bean> <!-- 開啓事物管理 --> <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 開啓註解 --> <!-- <tx:annotation-driven transaction-manager="transactionManager"/> --> <!-- 配置事物的行爲 --> <tx:advice id="myAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="fun*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <!-- 配置aop --> <aop:config> <!-- 配置切入點 --> <aop:pointcut expression="execution(* com.liy.service.impl.*.*(..))" id="myP"/> <aop:advisor advice-ref="myAdvice" pointcut-ref="myP"/> </aop:config> </beans>
測試
public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService bean = ac.getBean(UserService.class); bean.fun1(); }
註解的方式就相對簡單些
dao層
@Repository public class UserDao { @Resource private JdbcTemplate template;
service層
@Component public class UserServiceImpl implements UserService { @Resource private UserDao dao; @Transactional @Override public void fun1() { dao.add(); dao.update(); }
配置文件
<!-- 開啓spring的註解掃描 --> <context:component-scan base-package="com.sxt.*,com.liy.*"></context:component-scan> <bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate"> <!-- 構造注入關聯數據源 --> <constructor-arg name="dataSource" ref="dataSource"/> </bean> <!-- 配置數據源 --> <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource"> <!-- 配置數據庫的相關信息 --> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/again?characterEncoding=utf-8"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean> <!-- 開啓事物管理 --> <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 開啓事物管理的註解 --> <tx:annotation-driven transaction-manager="transactionManager"/>
測試類與另一種方式同樣
public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService bean = ac.getBean(UserService.class); bean.fun1(); }
這樣就沒有異常就都會執行 , 有異常就會回滾 , 就都不會執行成功