spring - 淺談spring的事務管理(程式設計式,宣告式(XML版和註解版))
阿新 • • 發佈:2018-11-19
事務管理的目的:
將若干sql語句作為一個整體 , 要麼全部成功 , 要麼全部失敗!
事務套路:
就是在sql語句前後增加事務!
aop套路 :
就是將 目的碼 和 增強程式碼 進行 解耦(分離)
spring提供的事務管理分為兩類:
一、程式設計式事務管理.(瞭解)
在需要事務管理目的碼中,新增事務管理的程式碼!
(有程式碼侵入事務管理方式 ,現在使用的非常少 )
缺點: 將目的碼和增強程式碼耦合在了一起 , 起不到aop的作用!
二、宣告式事務管理.(重點)
底層使用AOP的環繞通知 , 沒有任何程式碼侵入 .
(現在推薦使用)
宣告式事務管理兩種實現方式(XML和註解):
1.XML版-事務管理.
匯入依賴jar包 : pom.xml ( 看最後 )
dao層介面: AccountDao.java
public interface AccountDao { /** * 出賬 */ public void out(String outName, double money) throws SQLException; /** * 入賬 */ public void in(String inName, double money) throws SQLException; }
dao層實現類:AccountDaoImpl01.java
/**
* 使用xml版 , 對轉賬進行事務管理 .
*/
public class AccountDaoImpl01 extends JdbcDaoSupport implements AccountDao {
@Override
public void out(String outName, double money) throws SQLException {
String sql = "update account set money=money-? where name=?";
Object[] paramArr = {money, outName};
getJdbcTemplate().update(sql, paramArr);
}
@Override
public void in(String inName, double money) throws SQLException {
String sql = "update account set money=money+? where name=?";
Object[] paramArr = {money, inName};
getJdbcTemplate().update(sql, paramArr);
}
}
service層介面:
public interface AccountService {
/**
* 轉賬
*/
public void transfer(String outName, String inName, double money) throws SQLException;
}
service層實現類:
public class AccountServiceImpl01 implements AccountService {
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
@Override
public void transfer(String outName, String inName, double money) throws SQLException {
// 執行一組sql語句.
accountDao.out(outName, money);
// int i= 1/0;
accountDao.in(inName, money);
}
}
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_day01
jdbc.username=root
jdbc.password=root
Spring配置檔案: applicationContext_dao.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:context="http://www.springframework.org/schema/context"
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">
<!-- 關聯jdbc配置檔案 -->
<context:property-placeholder location="classpath:jdbc.properties" />
<!-- 將連線池交給spring處理 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- 將dao交給spring -->
<bean id="accountDaoImpl01" class="com.jxj.dao.impl.AccountDaoImpl01">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
Spring配置檔案: applicationContext_service.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: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/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">
<!-- 引入另一個配置檔案 -->
<import resource="classpath:xml/applicationContext_dao.xml" />
<!-- 目標類: 將service交給spring -->
<bean id="accountServiceImpl01" class="com.jxj.service.impl.AccountServiceImpl01">
<property name="accountDao" ref="accountDaoImpl01" />
</bean>
<!-- 增強類: 使用事務管理器進行管理事務. -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager" >
<!-- 對哪些方法進行增強事務 -->
<tx:attributes>
<tx:method name="transfer"/>
</tx:attributes>
</tx:advice>
<aop:config proxy-target-class="false" >
<aop:pointcut id="myPoint" expression="execution(* com.jxj.service..*.transfer(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="myPoint" />
</aop:config>
</beans>
測試類:
/**
* spring和junit進行整合.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:xml/applicationContext_service.xml"})
public class AccountServiceTest {
@Autowired
@Qualifier("accountServiceImpl01")
private AccountService accountService;
@Test
public void transfer() throws SQLException {
accountService.transfer("aaa","bbb",200);
}
}
2.註解版-事務管理
dao層介面: 同上.
dao層實現類: AccountDaoImpl02 .java
/**
* 使用註解版 , 對轉賬進行事務管理 .
*/
@Repository
public class AccountDaoImpl02 extends JdbcDaoSupport implements AccountDao {
// 根據型別注入連線池.
@Autowired
public void setDi(DataSource dataSource){
super.setDataSource(dataSource);
}
@Override
public void out(String outName, double money) throws SQLException {
String sql = "update account set money=money-? where name=?";
Object[] paramArr = {money, outName};
getJdbcTemplate().update(sql, paramArr);
}
@Override
public void in(String inName, double money) throws SQLException {
String sql = "update account set money=money+? where name=?";
Object[] paramArr = {money, inName};
getJdbcTemplate().update(sql, paramArr);
}
}
service層介面: 同上.
service層實現類: AccountServiceImpl02.java
@Service
public class AccountServiceImpl02 implements AccountService {
@Autowired
@Qualifier("accountDaoImpl02")
private AccountDao accountDao;
/**
給需要增強事務的方法 , 添加註解. (重點)
*/
@Transactional
public void transfer(String outName, String inName, double money) throws SQLException {
// 執行一組sql語句.
accountDao.out(outName, money);
// int i= 1/0;
accountDao.in(inName, money);
}
}
Spring配置檔案: applicationContext_dao.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:context="http://www.springframework.org/schema/context"
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">
<!-- 關聯jdbc配置檔案 -->
<context:property-placeholder location="classpath:jdbc.properties" />
<!-- 將連線池交給spring處理 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- 通過掃描包的方式 , 將dao交給spring處理 -->
<context:component-scan base-package="com.jxj.dao" />
</beans>
Spring配置檔案: applicationContext_service.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: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.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 引入外部配置檔案 -->
<import resource="classpath:annotation/applicationContext_dao.xml" />
<!-- 目標類: service的實現類交給spring-->
<context:component-scan base-package="com.jxj.service" />
<!-- 增強類: spring提供的事務管理器. -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 通知spring掃描帶有註解的方法. -->
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
測試類:
/**
* spring和junit進行整合.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:annotation/applicationContext_service.xml"})
public class AccountServiceTest {
@Autowired
@Qualifier("accountServiceImpl02")
private AccountService accountService;
@Test
public void transfer() throws SQLException {
accountService.transfer("aaa","bbb",200);
}
}
依賴: pom.xml
<dependencies>
<!-- 單元測試 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</dependency>
<!-- 日誌 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<!-- MySql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 連線池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
</dependencies>