Spring(3)之 Spring事務管理
Spring AOP
Spring JDBC
Spring 使用 AOP對事務進行實現
Spring 宣告式事務實現:
- XML方式
XML檔案中配置資料庫連線池、事務管理器、事務增強、aop:事務管理器中 ref引用 dataSource資料來源;事務增強中 transaction-manager用到事務管理器,並且設定哪些方法、是否只讀;aop中:配置切入點表示式並通過pointcut-ref引入、advice-ref引入事務通知 - 註解方式
① 設定註解方式實現事務:
<tx:annotation-driven transaction-manager=“txManager”/>
②
若放在方法上,則對於此方法新增事務
若放在類上,則對於此類中全部方法都有事務
程式中事務的控制:使用者——》action——》service——》dao
(一個程式執行成功,service要是成功,dao寫入資料庫成功)
事務控制放在service層
事務管理:
- 程式設計式事務 conn.setAutoCommit(false)
- Spring對於事務管理,宣告式事務
配置事務,AOP
0 .eg: 沒有事務操作時
模擬: 呼叫Dao,兩次操作,一次成功,一次失敗,沒有事務時沒有回滾,即使失敗的操作也會對資料庫產生影響
開發步驟:
1.後臺:資料庫、service、dao、entity
2.Dao使用 JdbcTemplate
3.物件的建立使用 IOC容器
0.1 UserDao.java
public class UserDao{ private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate){ this.jdbcTemplate=jdbcTemplate; } public void save(User user) throws Exception{ //新增方法 String sql="insert into user(username,age) values(?,?)"; jdbcTemplate.update(sql,new Object[]{user.getUsername(),user.getAge()}); } }
0.2 UserService.java
public class UserService{
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao=userDao;
}
public void save(User user) throws Exception{
userDao.save(user);
//出異常
int i=1/0;
userDao.save(user);
}
}
0.3 bean.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
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.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 建立連線池物件 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
<property name="user" value="root"></property>
<property name="password" value="12345"></property>
</bean>
<!-- JdbcTemplate工具類 -->
<!-- 建立jdbcTemplate物件(將dataSource注入) -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- dao -->
<!-- 建立UserDao物件(將jdbcTemplate注入) -->
<bean id="userDao" class="com.asd.spring.UserDao">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- service-->
<bean id="userService" class="com.asd.spring.UserService">
<property name="userDao" ref="userDao"></property>
</bean>
</beans>
Test.java
public class Test{
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean.xml");
@Test
public void test() throws Exception{
UserService userService=(UserService)applicationContext.getBean("userService");
User user=new User();
user.setUsername("測試");
user.setAge(9);
userService.save(user);
}
}
一、 XML方式配置事務
( bean.xml中:配置事務管理器、事務增強、aop:事務管理器中 ref引用 dataSource資料來源;事務增強中 transaction-manager用到事務管理器,並且設定哪些方法、是否只讀;aop中:配置切入點表示式並通過pointcut-ref引入、advice-ref引入事務通知。)
1.1 UserDao.java
public class UserDao{
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate){
this.jdbcTemplate=jdbcTemplate;
}
public void save(User user) throws Exception{ //新增方法
String sql="insert into user(username,age) values(?,?)";
jdbcTemplate.update(sql,new Object[]{user.getUsername(),user.getAge()});
}
}
1.2 UserService.java
public class UserService{
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao=userDao;
}
public void save(User user) throws Exception{
userDao.save(user);
//出異常
int i=1/0;
userDao.save(user);
}
}
1.3 bean.xml
(配置事務管理器、事務增強、aop:事務管理器中 ref引用 dataSource資料庫連線池;事務增強中 transaction-manager用到事務管理器,並且設定哪些方法、是否只讀;aop中:配置切入點表示式並通過pointcut-ref引入、advice-ref引入事務通知。)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
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.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 建立連線池物件 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
<property name="user" value="root"></property>
<property name="password" value="12345"></property>
</bean>
<!-- JdbcTemplate工具類 -->
<!-- 建立jdbcTemplate物件(將dataSource注入) -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- dao -->
<!-- 建立UserDao物件(將jdbcTemplate注入) -->
<bean id="userDao" class="com.asd.spring.UserDao">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- service-->
<bean id="userService" class="com.asd.spring.UserService">
<property name="userDao" ref="userDao"></property>
</bean>
<!-- Spring對於事務的管理 -->
<!-- 1.配置事務管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 2.配置事務管理增強(即如何管理) -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get" read-only="true"/>
<tx:method name="*" read-only="false"/>
</tx:attributes>
</tx:advice>
<!-- 3.配置AOP,攔截什麼方法(切入點表示式)+增強 -->
<aop:config>
<aop:pointcut id="pt" expression="execution(* com.asd.spring.UserService.save(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
</aop:config>
</beans>
Test.java
public class Test{
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean.xml");
@Test
public void test() throws Exception{
UserService userService=(UserService)applicationContext.getBean("userService");
User user=new User();
user.setUsername("測試2");
user.setAge(9);
userService.save(user);
}
}
二、 註解方式實現宣告式事務
(bean.xml中:開啟註解掃描、建立資料庫連線池 dataSource、配置事務管理器 txManager、配置事務註解:配置事務管理器時 ref引用 dataSource; 配置事務註解時 transaction-manager使用 txManager。UserService.java中:使用@Service、@Resource註解將 userDao注入進來,此時不需要用 setUserDao方法注入了;在方法或者類上使用@Transactional來新增事務。UserDao.java中:使用@Repository、@Resource註解將 jdbcTemplate注入進來,此時不需要用 setJdbcTemplate進行注入了。)
2.1 UserDao.java
(使用@Repository、@Resource註解將 jdbcTemplate注入進來,此時不需要用 setJdbcTemplate進行注入了。)
@Repository
public class UserDao{
@Resource
private JdbcTemplate jdbcTemplate;
public void save(User user) throws Exception{ //新增方法
String sql="insert into user(username,age) values(?,?)";
jdbcTemplate.update(sql,new Object[]{user.getUsername(),user.getAge()});
}
}
2.2 UserService.java
(使用@Service、@Resource註解將 userDao注入進來,此時不需要用 setUserDao方法注入了;在方法或者類上使用@Transactional來新增事務。)
@Service
@Transactional
public class UserService{
@Resource
private UserDao userDao;
// @Transactional
public void save(User user) throws Exception{
userDao.save(user);
//出異常
int i=1/0;
userDao.save(user);
}
}
2.3 bean.xml
(配置事務管理器、事務增強、aop:事務管理器中 ref引用 dataSource資料來源;事務增強中 transaction-manager用到事務管理器,並且設定哪些方法、是否只讀;aop中:配置切入點表示式並通過pointcut-ref引入、advice-ref引入事務通知。)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
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.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 開啟註解掃描 -->
<context:component-scan base-package="com.asd"></context:component-scan>
<!-- 建立連線池物件 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
<property name="user" value="root"></property>
<property name="password" value="12345"></property>
</bean>
<!-- JdbcTemplate工具類 -->
<!-- 建立jdbcTemplate物件(將dataSource注入) -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- Spring對於事務的管理 -->
<!-- 1.配置事務管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 2.註解方式實現事務,指定註解方式實現事務 -->
<tx:annotation-driven transaction-manager="txManager"/>
</beans>
Test.java
public class Test{
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean.xml");
@Test
public void test() throws Exception{
UserService userService=(UserService)applicationContext.getBean("userService");
User user=new User();
user.setUsername("測試3");
user.setAge(9);
userService.save(user);
}
}