Dao跨事务调用

新建Dbutils

//MyDBCPUtils
public class MyDBCPUtils
{

    private static DataSource ds;

    public static DataSource getDs()
    {
        return ds;
    }

    static
    {

        try
        {
            InputStream in = MyDBCPUtils.class.getClassLoader()
                    .getResourceAsStream("dbcpconfig.properties");
            Properties prop = new Properties();
            prop.load(in);
            // 框架提供的数据源
            BasicDataSourceFactory factory = new BasicDataSourceFactory();
            ds = factory.createDataSource(prop);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

    }
    //建立连接

    public static Connection getConnection() throws SQLException
    {
        return ds.getConnection(); // 返回一个被包装过的connection,所以用户可以直接关掉。关掉其实就是放回连接池了。
    }

    //释放资源
    public static void releaseResource(Statement st, ResultSet rs,
            Connection conn)
    {

        if (st != null)
        {
            try
            {
                st.close();
            }
            catch (SQLException e)
            {
                e.printStackTrace();
            }
        }
        if (rs != null)
        {
            try
            {
                rs.close();
            }
            catch (SQLException e)
            {
                e.printStackTrace();
            }
        }
        if (conn != null)
        {
            try
            {
                conn.close();
            }
            catch (SQLException e)
            {
                e.printStackTrace();
            }
        }
    }

}

配置文件放在src下

#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mytest
username=root
password=123456

#<!-- 初始化连接 -->
initialSize=10

#最大连接数量
maxActive=50

#<!-- 最大空闲连接 -->
maxIdle=20

#<!-- 最小空闲连接 -->
minIdle=5

#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=60000


#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;] 
#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=utf8

#指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true

#driver default 指定由连接池所创建的连接的只读(read-only)状态。
#如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
defaultReadOnly=

#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=REPEATABLE_READ

新建JavaBean

package com.cskaoyan.bean;

public class Account
{

    private String username;
    private int money;
    public String getUsername()
    {
        return username;
    }
    public void setUsername(String username)
    {
        this.username = username;
    }
    public int getMoney()
    {
        return money;
    }
    public void setMoney(int money)
    {
        this.money = money;
    }
    public Account(String username, int money)
    {
        super();
        this.username = username;
        this.money = money;
    }
    public Account()
    {
        super();
        // TODO Auto-generated constructor stub
    }
    @Override
    public String toString()
    {
        return "Account [username=" + username + ", money=" + money + "]";
    }

}

UserDao和UserService来处理转账业务

//UserService

import com.cskaoyan.bean.Account;
import com.cskaoyan.dao.TransactionUtils;
import com.cskaoyan.dao.UserDao;
import com.cskaoyan.dao.UserDaoImpl;
import com.cskaoyan.db.MyDBCPUtils;

public class UserService
{

    // 转账是一个事务,要么全部成功,要么全部不成功
    public void transferMoney(String usernameFrom, String usernameTo, int money)
    {

        UserDao dao = new UserDaoImpl();
        dao.transfer(usernameFrom, usernameTo, money);

    }


    // 把转账的业务逻辑放回到service层
    public void transferMoney2(String usernameFrom, String usernameTo, int money)
    {

        UserDao dao = new UserDaoImpl();

        Connection connection = null;
        try
        {
            //开启事务
            TransactionUtils.startTransaction();

            // 需要先查询下多少钱,然后再转
            Account accout_from = dao.getAccout(usernameFrom);// 汇款人
            Account accout_to = dao.getAccout(usernameTo);// 收款人

            // 业务计算
            accout_from.setMoney(accout_from.getMoney() - money);
            // 把usernameFrom 更新成新的accout_from
            dao.updateAccout(accout_from); 


            int i = 1 / 0;// 此处应当有计算
            accout_to.setMoney(accout_to.getMoney() + money);
            dao.updateAccout(accout_to);// 把usernameTo更新成新的accout_to

            //提交事务
            TransactionUtils.commitTransaction();
        }
        catch (Exception e)
        {
            e.printStackTrace();
            //回滚事务
            TransactionUtils.rollbackTransaction();
        }

    }

}

//UserDao
public class UserDaoImpl implements UserDao
{

    @Override
    public void transfer(String userfrom, String userto, int money)
    {
        QueryRunner queryRunner = new QueryRunner(MyDBCPUtils.getDs());
        try
        {
//          转账
            queryRunner.update("update account set money = money -? where username = ?",
                    money, userfrom);
            queryRunner.update( "update account set money = money +? where username = ?",
                    money, userto);
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
    }

    // 外界会调用DAO去更新一下数据库的信息
    @Override
    public void updateAccout(Account account)
    {
        QueryRunner queryRunner = new QueryRunner(MyDBCPUtils.getDs());
        try
        {
            //修改账户
            queryRunner.update(TransactionUtils.getConnection(),"update account set money =  ? where username = ?",
                    account.getMoney(), account.getUsername());
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
    }

    @Override
    public Account getAccout(String username)
    {
        //查找账户
        Account account = null;

        QueryRunner queryRunner = new QueryRunner(MyDBCPUtils.getDs());
        try
        {
            account = queryRunner.query(
                    "select *  from account   where username = ?;",

                    new BeanHandler<Account>(Account.class),

                    username);

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

        return account;

    }
}

JunitTest

@Test
    public void testTrans()
    {
        UserService service=new UserService();
        service.transferMoney("e", "f", 100);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值