vlambda博客
学习文章列表

Spring_33_3 | 回顾:事务支持转账_三层架构/XML



Spring_33_3 | 回顾:事务支持转账_三层架构/XML
  Spring_33_3 | 回顾:事务支持转账_三层架构/XML


Spring_33_3 | 回顾:事务支持转账_三层架构/XML
 1package com.tz.dao.impl;
2
3import com.tz.dao.AccountDao;
4import com.tz.domain.Account;
5import com.tz.utils.ConnectionUtils;
6import org.apache.commons.dbutils.QueryRunner;
7import org.apache.commons.dbutils.handlers.BeanListHandler;
8import java.sql.SQLException;
9import java.util.List;
10//import org.springframework.jdbc.core.BeanPropertyRowMapper;
11//import org.springframework.jdbc.core.support.JdbcDaoSupport;
12//import org.springframework.jdbc.core.JdbcTemplate;
13
14
15//public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{
16//
17//    //3.注:在方法里面加了继承"extends JdbcDaoSupport"后,就可以删除重复代码
18//    private JdbcTemplate jdbcTemplate;
19//
20//    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
21//       this.jdbcTemplate = jdbcTemplate;
22//    }
23
24public class AccountDaoImpl implements AccountDao{
25
26    private QueryRunner runner;
27    private ConnectionUtils connectionUtils;
28
29    public void setRunner(QueryRunner runner) {
30        this.runner = runner;
31    }
32
33    public void setConnectionUtils(ConnectionUtils connectionUtils) {
34        this.connectionUtils = connectionUtils;
35    }
36
37
38    /**
39     * 按姓名查询
40     * @param accountName
41     * @return
42     */

43                        //    注:拿来做参考
44                        //    @Override
45                        //    public Account findAccountByName(String accountName) {
46                        //        List<Account> accounts_name = super.getJdbcTemplate().query("select * from account where name=?", new BeanPropertyRowMapper<Account>(Account.class), accountName);
47                        //        if(accounts_name.isEmpty()){
48                        //            return null;
49                        //        }
50                        //        if(accounts_name.size()>1){
51                        //            throw new RuntimeException("结果集不唯一");
52                        //        }
53                        //        return accounts_name.get(0);
54                        //    }
55
56    @Override
57    public Account findAccountByName(String accountName) {
58        try {
59            //把"connectionUtils.getThreadConnection()",意思是手动开启事务连接
60            //BeanListHandler:将结果集中的每一行数据都封装到一个对应JavaBean实例中,存放到List里面.
61            List<Account> accounts_name = runner.query(connectionUtils.getThreadConnection(),"select * from account where name=?"new BeanListHandler<Account>(Account.class), accountName);
62            if(accounts_name.isEmpty()){
63                return null;
64            }
65            if(accounts_name.size()>1){
66                throw new RuntimeException("结果集不唯一");
67            }
68            return accounts_name.get(0);
69        } catch (SQLException e) {
70            throw new RuntimeException(e);  //代码是从上往下执行,遇到异常后再执行下去就没意义,这是手动关闭
71        }
72    }
73
74    /**
75     * 更新
76     * @param account
77     */

78    @Override
79    public void updateAccount(Account account) {
80        try {
81            runner.update(connectionUtils.getThreadConnection(),"update account set name=?,money=? where id =?",account.getName(),account.getMoney(),account.getId());
82        } catch (SQLException e) {
83            e.printStackTrace();
84        }
85    }
86}


 1package com.tz.dao;
2
3import com.tz.domain.Account;
4
5/**
6 * Created by Administrator on 2020/1/16 0016.
7 */

8public interface AccountDao {
9
10    //根据名称查询
11    Account findAccountByName(String accountName);
12    //更新
13    void updateAccount(Account account);
14}





Spring_33_3 | 回顾:事务支持转账_三层架构/XML
 1package com.tz.domain;
2
3/**
4 * Created by Administrator on 2020/1/16 0016.
5 */

6public class Account {
7    private Integer id;
8    private String name;
9    private Float money;
10
11    public Integer getId() {
12        return id;
13    }
14
15    public void setId(Integer id) {
16        this.id = id;
17    }
18
19    public String getName() {
20        return name;
21    }
22
23    public void setName(String name) {
24        this.name = name;
25    }
26
27    public Float getMoney() {
28        return money;
29    }
30
31    public void setMoney(Float money) {
32        this.money = money;
33    }
34
35    @Override
36    public String toString() {
37        return "Account{" +
38                "id=" + id +
39                ", name='" + name + '\'' +
40                ", money=" + money +
41                '}';
42    }
43}





Spring_33_3 | 回顾:事务支持转账_三层架构/XML
 1package com.tz.service.impl;
2
3import com.tz.dao.AccountDao;
4import com.tz.domain.Account;
5import com.tz.service.AccountService;
6import com.tz.utils.TransactionManager;
7
8/**
9 * Created by Administrator on 2020/1/17 0017.
10 */

11public class AccountServiceImpl implements AccountService{
12    //把持久层引进来
13    private AccountDao accountDao;
14    //事务
15    private TransactionManager txManager;
16
17    public void setAccountDao(AccountDao accountDao) {
18        this.accountDao = accountDao;
19    }
20
21    public void setTxManager(TransactionManager txManager) {
22        this.txManager = txManager;
23    }
24
25    /**
26     * 转账操作
27     * @param sourceName 转出账户名称
28     * @param targetName 转入账户名称
29     * @param money
30     */

31    @Override
32    public void transfer(String sourceName, String targetName, Float money) {
33        try {
34            //开启事务
35            txManager.beginTransaction();
36                    //根据账户名查询转出账户
37                    Account source = accountDao.findAccountByName(sourceName);
38                    //根据账户名查询转入账户
39                    Account target = accountDao.findAccountByName(targetName);
40                    //转出账户减钱
41                    source.setMoney(source.getMoney()-money);
42                    //转入账户加钱
43                    target.setMoney(target.getMoney()+money);
44                    //更新转出账户
45                    accountDao.updateAccount(source);
46                    //模拟异常产生
47                    int i = 1/0;
48                    //更新转入账户
49                    accountDao.updateAccount(target);
50            //提交事务
51            txManager.commit();
52        } catch (Exception e) {
53            txManager.rollback();
54            e.printStackTrace();
55        } finally {
56            //释放连接
57            txManager.release();
58        }
59    }
60}


 1package com.tz.service;
2
3/**
4 * Created by Administrator on 2020/1/17 0017.
5 */

6public interface AccountService {
7    /**
8     * 转账操作
9     * @param sourceName 转出账户名称
10     * @param targetName 转入账户名称
11     * @param money
12     */

13    void transfer(String sourceName,String targetName,Float money);
14}





Spring_33_3 | 回顾:事务支持转账_三层架构/XML
 1package com.tz.utils;
2
3import javax.sql.DataSource;
4import java.sql.Connection;
5import java.sql.SQLException;
6
7/**
8 * 与本地/当前线程连接工具类
9 */

10public class ConnectionUtils {
11    private ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
12
13    private DataSource dataSource;
14
15    public void setDataSource(DataSource dataSource) {
16        this.dataSource = dataSource;
17    }
18
19    /**
20     * 获取线程上的连接
21     * @return
22     */

23    public Connection getThreadConnection(){
24        try {                       //try{}catch(){}快捷键:Ctil+Alt+t , 前提是选中
25            //先从线程上拿连接
26            Connection conn = tl.get();
27            //判断当前线程上是否有连接
28            if(conn==null){
29                //从数据源中拿
30                conn = dataSource.getConnection();
31                //与当前线程绑定
32                tl.set(conn);
33            }
34            return conn;
35        } catch (SQLException e) {
36            throw new RuntimeException(e);
37        }
38    }
39
40    //把当前线程与连接解绑/移除
41    public void removeConnection(){
42        tl.remove();
43    }
44}


 1package com.tz.utils;
2
3import java.sql.SQLException;
4
5/**
6 * 事务工具类
7 */

8public class TransactionManager {
9    //把线程工具类引入进来
10    private ConnectionUtils connectionUtils;
11
12    public void setConnectionUtils(ConnectionUtils connectionUtils) {
13        this.connectionUtils = connectionUtils;
14    }
15
16    /**
17     * 开启事务
18     *
19     * begin:开始
20     * Transaction:交易,业务,买卖;办理;处理
21     *
22     * connectionUtils:这是自己设置的线程工具类
23     * getThreadConnection:获取线程连接
24     * setAutoCommint:设置自动提交
25     */

26    public void beginTransaction(){
27        try {
28            connectionUtils.getThreadConnection().setAutoCommit(false);
29        } catch (SQLException e) {
30            e.printStackTrace();
31        }
32    }
33
34    /**
35     * 提交事务
36     */

37    public void commit(){
38        try {
39            connectionUtils.getThreadConnection().commit();
40        } catch (SQLException e) {
41            e.printStackTrace();
42        }
43    }
44
45    /**
46     * 回滚事务
47     */

48    public void rollback(){
49        try {
50            connectionUtils.getThreadConnection().rollback();
51        } catch (SQLException e) {
52            e.printStackTrace();
53        }
54    }
55
56    /**
57     * 释放连接
58     */

59    public void release(){
60        try {
61            connectionUtils.getThreadConnection().close();
62            connectionUtils.removeConnection(); //解绑,还到池中
63        } catch (SQLException e) {
64            e.printStackTrace();
65        }
66    }
67}





Spring_33_3 | 回顾:事务支持转账_三层架构/XML
 1<?xml version="1.0" encoding="UTF-8"?>
2<beans xmlns="http://www.springframework.org/schema/beans"
3       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4       xsi:schemaLocation="
5        http://www.springframework.org/schema/beans
6        https://www.springframework.org/schema/beans/spring-beans.xsd"
>

7
8        <!--配置业务层Service-->
9        <bean id="accountService" class="com.tz.service.impl.AccountServiceImpl">
10            <property name="accountDao" ref="accountDao"></property>
11            <property name="txManager"  ref="txManager"></property>
12        </bean>
13
14        <!--配置持久层Dao-->
15        <bean id="accountDao" class="com.tz.dao.impl.AccountDaoImpl">
16                        <!--<property name="jdbcTemplate" ref="jdbcTemplate"></property>-->
17            <property name="runner" ref="runner"></property>
18            <property name="connectionUtils" ref="connectionUtils"></property>
19        </bean>
20
21        <!--配置事务TransactionManager-->
22        <bean id="txManager" class="com.tz.utils.TransactionManager">
23            <property name="connectionUtils" ref="connectionUtils"></property>
24        </bean>
25
26        <!--配置ConnectionUtils-->
27        <bean id="connectionUtils" class="com.tz.utils.ConnectionUtils">
28            <property name="dataSource" ref="dataSource"></property>
29        </bean>
30
31        <!--配置QueryRunner-->
32        <bean id="runner" class="org.apache.commons.dbutils.QueryRunner"></bean>
33
34                        <!--配置JdbcTemplate-->
35                        <!-- <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
36                                <property name="dataSource" ref="dataSource"></property>
37                             </bean>
38                        -->

39
40        <!--配置数据源DataSource-->
41        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><!--这是JdbcTemplate java里面内置的配置,要配置引用-->
42            <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
43            <property name="url" value="jdbc:mysql:///test"></property>
44            <property name="username" value="root"></property>
45            <property name="password" value="root"></property>
46        </bean>
47</beans>





Spring_33_3 | 回顾:事务支持转账_三层架构/XML
 1package com.tz.test;
2
3import com.tz.service.AccountService;
4import org.junit.Test;
5import org.junit.runner.RunWith;
6import org.springframework.beans.factory.annotation.Autowired;
7import org.springframework.test.context.ContextConfiguration;
8import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
9
10@RunWith(SpringJUnit4ClassRunner.class)     //junit单元测试
11@ContextConfiguration(locations="classpath:bean.xml")   //读取bean.xml配置文件注解
12public class AccountTest {
13
14    @Autowired
15    private AccountService as;
16
17    @Test
18    public void test1(){
19        as.transfer("ccc","xiaoxiao",100f);
20    }
21}





Spring_33_3 | 回顾:事务支持转账_三层架构/XML
 1<?xml version="1.0" encoding="UTF-8"?>
2<project xmlns="http://maven.apache.org/POM/4.0.0"
3         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

5    <modelVersion>4.0.0</modelVersion>
6
7    <groupId>com.tz</groupId>
8    <artifactId>SpringIOC</artifactId>
9    <version>1.0-SNAPSHOT</version>
10
11    <dependencies>
12        <dependency>
13            <groupId>org.springframework</groupId>
14            <artifactId>spring-context</artifactId>
15            <version>5.0.8.RELEASE</version>
16        </dependency>
17
18        <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
19        <dependency>
20            <groupId>org.springframework</groupId>
21            <artifactId>spring-jdbc</artifactId>
22            <version>5.0.8.RELEASE</version>
23        </dependency>
24
25        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
26        <dependency>
27            <groupId>mysql</groupId>
28            <artifactId>mysql-connector-java</artifactId>
29            <version>5.0.8</version>
30        </dependency>
31
32        <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
33        <dependency>
34            <groupId>org.springframework</groupId>
35            <artifactId>spring-tx</artifactId>
36            <version>5.0.8.RELEASE</version>
37        </dependency>
38
39        <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
40        <dependency>
41            <groupId>org.springframework</groupId>
42            <artifactId>spring-test</artifactId>
43            <version>5.0.8.RELEASE</version>
44            <scope>test</scope>
45        </dependency>
46
47        <!-- https://mvnrepository.com/artifact/commons-dbutils/commons-dbutils -->
48        <dependency>
49            <groupId>commons-dbutils</groupId>
50            <artifactId>commons-dbutils</artifactId>
51            <version>1.4</version>
52        </dependency>
53
54        <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
55        <dependency>
56            <groupId>com.mchange</groupId>
57            <artifactId>c3p0</artifactId>
58            <version>0.9.5.2</version>
59        </dependency>
60
61        <dependency>
62            <groupId>junit</groupId>
63            <artifactId>junit</artifactId>
64            <version>4.12</version>
65        </dependency>
66    </dependencies>
67
68</project>






控制台输出结果
Spring_33_3 | 回顾:事务支持转账_三层架构/XML


目录大纲 Directory outline