Spring基于注解的声明式事务控制

### 注解配置声明式事务控制解析

①使用 @Transactional 在需要进行事务控制的类或是方法上修饰,注解可用的属性同 xml 配置方式,例如隔离级别、传播行为等。

②注解使用在类上,那么该类下的所有方法都使用同一套注解参数配置。

③使用在方法上,不同的方法可以采用不同的事务参数配置。

④Xml配置文件中要开启事务的注解驱动<tx:annotation-driven />

### 知识要点

**注解声明式事务控制的配置要点**

- 平台事务管理器配置(xml方式)

- 事务通知的配置(@Transactional注解配置)

- 事务注解驱动的配置 <tx:annotation-driven/>

配置文件

<?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"
       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.code_g"/>

    <context:property-placeholder location="jdbc.properties"/>

    <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>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

<!--    <bean id="accountDao" class="com.code_g.dao.Impl.AccountDaoImpl">-->
<!--        <property name="jdbcTemplate" ref="jdbcTemplate"/>-->
<!--    </bean>-->

<!--    <bean id="accountService" class="com.code_g.service.Impl.AccountServiceImpl">-->
<!--        <property name="accountDao" ref="accountDao"/>-->
<!--    </bean>-->

<!--    事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>

<!--&lt;!&ndash;    事务通知&ndash;&gt;-->
<!--    <tx:advice id="myAdvice" transaction-manager="transactionManager">-->
<!--        <tx:attributes>-->
<!--            <tx:method name="*"/>-->
<!--        </tx:attributes>-->
<!--    </tx:advice>-->

<!--&lt;!&ndash;事务织入&ndash;&gt;-->
<!--    <aop:config>-->
<!--        <aop:advisor advice-ref="myAdvice" pointcut="execution(* com.code_g.service.impl.*.*(..))"/>-->
<!--    </aop:config>-->

</beans>

dao层实现类

package com.code_g.dao.Impl;

import com.code_g.dao.AccountDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;

@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {

    @Resource(name = "jdbcTemplate")
    private JdbcTemplate jdbcTemplate;

    @Override
    public void out(String outMan, double money) {
        jdbcTemplate.update("update account set money = money - ? where name = ?",money,outMan);
    }

    @Override
    public void in(String inMan, double money) {
        jdbcTemplate.update("update account set money = money + ? where name = ?",money,inMan);
    }
}

service层实现类

package com.code_g.service.Impl;

import com.code_g.dao.AccountDao;
import com.code_g.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

@Service("accountService")
public class AccountServiceImpl implements AccountService {
    @Resource(name = "accountDao")
    private AccountDao accountDao;


    @Override
    @Transactional  //事务通知注解
    public void transfer(String outMan, String inMan, double money) {
        accountDao.out(outMan,money);
//        int i = 1/0;
        accountDao.in(inMan,money);
    }
}


测试类

package com.code_g.test;

import com.code_g.domain.Account;
import com.code_g.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.omg.CORBA.PRIVATE_MEMBER;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TxTest {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private AccountService accountService;

    @Test
    public void test1(){
        Account query = jdbcTemplate.queryForObject("select * from account where name = ?", new BeanPropertyRowMapper<Account>(Account.class), "郭奉孝");
        System.out.println(query);
    }

    @Test
    public void test2(){
//        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//        AccountService accountService = (AccountService) applicationContext.getBean("accountService");
        accountService.transfer("郭奉孝","曹操",500);
    }
}

posted @ 2021-05-22 19:17  code-G  阅读(75)  评论(0编辑  收藏  举报