A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 不二晨 金牌黑马   /  2019-3-8 10:24  /  817 人查看  /  1 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

事务示例之转账

1.创建数据库,填充数据:

数据库名称db_account,表名tb_account,插入几条数据。



2.配置数据库信息

在项目的WebContent/META-INF目录下创建一个context.xml文件。如图:


在context.xml文件中配置:

<?xml version="1.0" encoding="UTF-8"?>
<Context>      
    <Resource name="jdbc/account" auth="Container" type="javax.sql.DataSource"
    maxActive="100" maxIdle="30" maxWait="10000"
    username="root" password="root" driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/db_account"/>
</Context>
1
2
3
4
5
6
7
这里采用的是Javaweb自带的DBCP配置,详细参考Javaweb配置常用的数据源配置

3.创建项目结构

如图:



AccountDao

public interface AccountDao {
    /**
     * 更新账户
     * @param account
     */
    public boolean updateAccount(Account account) throws SQLException;  

    /**
     * 查找账户
     * @param account
     * @return
     */
    public Account findAccountByName(String account);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
AccountDaoImpl

public class AccountDaoImpl implements AccountDao{

    public AccountDaoImpl() {

    }

    @Override
    public boolean updateAccount(Account account) {
        Connection conn = ManagerThreadLocal.getConn();
        if(conn==null){
            throw new NullPointerException("Connection is null");
        }

        PreparedStatement ps = null;
        try {
             ps = conn.prepareStatement("update tb_account set money=? where name=?");
             if(ps==null){
                 throw new NullPointerException("PreparedStatement is null");
             }
             ps.setDouble(1, account.getMoney());
             ps.setString(2, account.getName());
             int i = ps.executeUpdate();
             return i>0;

        } catch (SQLException e) {
            e.printStackTrace();
        }

        return false;
    }

    @Override
    public Account findAccountByName(String account) {

        Connection conn = ManagerThreadLocal.getConn();

        if(conn==null){
            throw new NullPointerException("Connection is null");
        }

        Account a = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
             ps = conn.prepareStatement("select name,money from tb_account where name=?");
             if(ps==null){
                 throw new NullPointerException("PreparedStatement is null");
             }
             ps.setString(1, account);

             rs = ps.executeQuery();
             if(rs==null){
                 throw new NullPointerException("ResultSet is null");
             }

             if(rs.next()){
                 a = new Account();
                 a.setName(rs.getString(1));
                 a.setMoney(rs.getDouble(2));
                 return a;
             }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return a;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
Account

public class Account {
    private int id;
    private String name;
    private double money;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getMoney() {
        return money;
    }
    public void setMoney(double money) {
        this.money = money;
    }
    @Override
    public String toString() {
        return "Account [id=" + id + ", name=" + name + ", money=" + money + "]";
    }   
   }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
AccountService

public interface AccountService {
        /**
         * 转账
         * @param fromName
         * @param toName
         * @param money
         */
        public void transfer(String fromName,String toName,double money);
    }
1
2
3
4
5
6
7
8
9
AccountServiceImpl

public class AccountServiceImpl implements AccountService{

    @Override
    public void transfer(String fromName, String toName, double money) {

        AccountDao accountDao = new AccountDaoImpl();
        Account fromAccount = accountDao.findAccountByName(fromName);
        if(fromAccount==null){
            throw new RuntimeException("你的账户不存在");
        }
        if(money > fromAccount.getMoney()){
            throw new RuntimeException("你的账户的钱不够");
        }
        fromAccount.setMoney(fromAccount.getMoney() - money);

        Account toAccount = accountDao.findAccountByName(toName);
        if(toAccount==null){
            throw new RuntimeException("对方的账户不存在");
        }
        toAccount.setMoney(toAccount.getMoney() + money);

        //开启事务
        ManagerThreadLocal.startTransaction();

        try {
                    accountDao.updateAccount(fromAccount);
            //int i = 10/0; //测试事务代码
            accountDao.updateAccount(toAccount);
            //提交事务
            ManagerThreadLocal.commit();
        } catch (SQLException e) {
            //事务回滚
            ManagerThreadLocal.rollback();
            e.printStackTrace();
        }finally {
            ManagerThreadLocal.close();
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
TransferServlet

    @WebServlet({ "/TransferServlet", "/transfer" })
public class TransferServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

        public TransferServlet() {
            super();

        }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        AccountService accountService = new AccountServiceImpl();
        accountService.transfer("10010", "10000", 100);


    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
ManagerThreadLocal

public class ManagerThreadLocal {

    private static ThreadLocal<Connection> tl = new ThreadLocal<>();

    private static Connection getConnection(){
        Connection conn  = null;
        try {
            Context context = new InitialContext();
            DataSource dataSource = (DataSource) context.lookup("java:/comp/env/jdbc/account");
            conn = (Connection) dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (NamingException e) {
            e.printStackTrace();
        }
        return conn;
    }

    public static Connection getConn(){
        Connection conn = null;
        conn = tl.get();
        if(conn==null){
            conn = getConnection();
            tl.set(conn);
        }
        return conn;
    }

    public static void startTransaction(){
        try {
            getConn().setAutoCommit(false);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void commit(){
        try {
            getConn().commit();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void rollback(){
        try {
            getConn().rollback();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void close(){
        try {
            getConn().close();
            tl.remove();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
---------------------
【转载】
作者:张行之
来源:CSDN
原文:https://blog.csdn.net/qq_33689414/article/details/63251216
版权声明:本文为博主原创文章,转载请附上博文链接!

1 个回复

倒序浏览
奈斯,感谢分享
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马