Java事务(三) - 使用ThreadLocal
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java事务(三) - 使用ThreadLocal,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2835字,纯文字阅读大概需要5分钟。
内容图文
![Java事务(三) - 使用ThreadLocal](/upload/InfoBanner/zyjiaocheng/1308/0be06fa09ed94bd2934a29c52371c256.jpg)
一. 为什么使用ThreadLocal:
在上一篇博文中, 我们通过传递Connection的方式来控制事务, 这种方法可以达到目的, 但让人看的不爽,
如果涉及到调用多个service, 那我是不是还得从controller层传递Connection?
ThreadLocal的用法见上一篇博客, 该类保证一个类的实例变量在各个线程中都有一份单独的拷贝,
从而不会影响其他线程中的实例变量
二. 如何使用ThreadLocal:
1. 写一个TransactionManager类:
/** * 管理事务 */ public class TransactionManager { private static ThreadLocal<Connection> local = new ThreadLocal<Connection>(); // 开启事务 public static void beginTransaction() throws SQLException { Connection conn = JDBCUtils.getConnection(); conn.setAutoCommit(false); // 将连接存入threadLocal local.set(conn); } // 回滚事务 public static void rollback() throws SQLException { Connection conn = local.get(); if (conn != null) { conn.rollback(); conn.close(); // 清空threadLocal local.remove(); } } // 提交事务 public static void commitAndClose() throws SQLException { Connection conn = local.get(); if (conn != null) { conn.commit(); conn.close(); // 清空threadLocal local.remove(); } } // 获取数据库连接 public static Connection getConnection() { return local.get(); } }使用ThreadLocal, 确保相同的线程获取到的是同一个连接.
2.修改业务处理类
/** * 业务逻辑层 */ public class AccountService { public void transfer(Account outAccount, Account inAccount, int money) throws SQLException { // 开启 事务 TransactionManager.beginTransaction(); // 查询两个账户 AccountDAO accountDAO = new AccountDAO(); outAccount = accountDAO.findAccountById(outAccount.getId()); inAccount = accountDAO.findAccountById(inAccount.getId()); // 转账 - 修改原账户金额 outAccount.setMoney(outAccount.getMoney() - money); inAccount.setMoney(inAccount.getMoney() + money); try { // 更新账户金额 accountDAO.update(outAccount); accountDAO.update(inAccount); // 转账成功, 提交事务 TransactionManager.commitAndClose(); } catch (Exception e) { // 转账失败, 回滚事务 TransactionManager.rollback(); e.printStackTrace(); } } }
使用TransactionManager来管理事务, 代码变得更加简洁.
3. 修改Dao类
/** * DAO层: CRUD */ public class AccountDAO { // 查询账户 public Account findAccountById(int id) throws SQLException { String sql = "select * from account where id = ?"; Object[] params = {id}; QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource()); return queryRunner.query(sql, new BeanHandler<Account>(Account.class), params); } // 更新账户 public void update(Account account) throws SQLException { String sql = "update account set name = ?, money = ? where id = ?"; Object[] params = {account.getName(), account.getMoney(), account.getId()}; // 从threadLocal中获取连接, 同一个线程拿到的是同一个连接 Connection conn = TransactionManager.getConnection(); QueryRunner queryRunner = new QueryRunner(); queryRunner.update(conn, sql, params); } }
不需要传递Connection, 直接从TransactionManager中获取连接.
三. 总结:
service和dao都是通过TransactionManager来获取Connection, 同一个线程中, 它们在整个事务处理过程中使用了相同的Connection对象, 所以事务会处理成功, dao中没有接受和业务无关的对象, 消除了api污染, 另外使用TransactionManager来管理事务, 使service层的代码变简洁了.
原文:http://blog.csdn.net/zdp072/article/details/39214867
内容总结
以上是互联网集市为您收集整理的Java事务(三) - 使用ThreadLocal全部内容,希望文章能够帮你解决Java事务(三) - 使用ThreadLocal所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。