spring - 浅谈spring的事务管理(编程式,声明式(XML版和注解版))

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_42986107/article/details/84241495

事务管理的目的:
              将若干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>

猜你喜欢

转载自blog.csdn.net/qq_42986107/article/details/84241495
今日推荐