数据库事务
来源:互联网 发布:查找html源码 编辑:程序博客网 时间:2024/06/18 04:36
一.事务的概念
事务指的是逻辑上的一组操作,组成这组操作的各个单元要么全都成功执行,要么全都失败不执行
事务的作用:保证在一个事务中的多个操作的执行与否一致(都执行或都不执行)
二.常见事务操作
2.1 MySQL的事务操作:
和事务操作相关的SQL语句:
MySQL的事务使用案例:
1.准备工作:
选择数据库表,并准备点数据(我用一个已有的库和表)
//查看所有数据库show databases;//选中shop库use shop//查询shop库中orders表中的所有数据(没有数据就搞一点)select * from orders;
开始时total=7926的数据name值为“lili”
2.设置事务是否自动提交
//查看MySQL事务提交方式show variables like '%commit%';
autocommit属性的值代表属性提交方式(OFF为不自动提交,ON为自动提交)
//设置事务不自动提交 0对应OFF关闭,1对应ON开启set autocommit = 0
3.事务手动提交示例:
3.1执行更新后执行回滚
start transaction;update orders set name='feifei' where total = 7926;rollback;
使用rollback后事务回滚,更新方法没有执行,lili的值没有变
3.2执行更新后不执行回滚
start transaction;update orders set name='feifei' where total = 7926;commit;
使用commit方法将事务提交,更新语句执行,lili变为feifei
2.2JDBC的事务操作
JDBC通过Connection类的方法进行事务开启/提交/回滚
2.3DBUtils的事务操作
DBUtils的事务操作涉及Connection类和QueryRunner类
三.事务使用案例:
黑马商城订单付款模块,向商家转账
1.我的订单页面order_list.jsp,点击付款
2.order_info.jsp确认订单
3.transfer.jsp确认付款
4.OrderServlet接受参数,调用后台OrderService
5.在OrderService中进行事务管理
public void transfer(String name, String to, String money) throws SQLException, ClassNotFoundException { int money_int = Integer.parseInt(money); /**1.创建连接对象*/ Connection connection = null; try { /**2.开启数据库连接,整个事务操作中,只能有这一个数据库连接,若开启了多个连接,则无法正确的完成数据库事务的管理*/ connection = JDBCUtils.getDataSource(); /**3.开启事务*/ connection.setAutoCommit(false); /**4.1 事务操作,转出,connection作为参数传递*/ orderDao.outMoney(connection,name,money_int); /**4.2 事务操作,转入,connection作为参数传递*/ orderDao.inMoney(connection,to,money_int); 事务操作,转出 /**5.事务提交*/ connection.commit(); }catch (Exception e){ try{ if (connection != null){ /**6.发生错误则事务回滚*/ connection.rollback(); } }catch (Exception e2){ } throw new RuntimeException(e); }finally { /**7.关闭数据库资源*/ JDBCUtils.closeResouce(connection,null,null); } }
6.OrderDao中进行事务的数据库操作
@Override public void outMoney(Connection connection, String username, int money) throws SQLException { Statement statement = null; PreparedStatement preparedStatement = null; try { String qsql = "SELECT name FROM user WHERE username = '"+ username + "'"; statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,CONCUR_READ_ONLY); ResultSet resultSet = statement.executeQuery(qsql); boolean bool = resultSet.first(); String name = resultSet.getString("name"); /**转出操作*/ String sql = "update useraccount set money = money - ? where name = ?"; preparedStatement = connection.prepareStatement(sql); preparedStatement.setInt(1,money); preparedStatement.setString(2,name); int change = preparedStatement.executeUpdate(); System.out.println(change); }catch (Exception e){ throw new RuntimeException(e); }finally { //关闭资源 JDBCUtils.closeResouce(null,preparedStatement,null); } } @Override public void inMoney(Connection connection, String to, int money) throws SQLException { PreparedStatement preparedStatement = null; try { /**转入操作*/ String sql = "update selleraccount set money = money + ? where name = ?"; preparedStatement = connection.prepareStatement(sql); preparedStatement.setInt(1,money); preparedStatement.setString(2,to); int change = preparedStatement.executeUpdate(); System.out.println(change); }catch (Exception e){ throw new RuntimeException(e); }finally { /**关闭资源*/ JDBCUtils.closeResouce(null,preparedStatement,null); } }
优化:使用ThreadLocal代替传递数据库连接
在以上的代码中,Connection数据库连接对象在Service层创建,不符合分层管理的理念,可以使用ThreadLocal类来进行部分优化,不再将Connection对象作为参数进行传递
1.ThreadLocal简介:
该类提供了线程局部 (thread-local)变量。只有和该变量在同一线程中,才能访问该线程局部变量
ThreadLocal 实例通常是类中的 private static 字段,通常将状态与某一个线程(例如,用户 ID 或事务 ID)相关联,用于在一个线程中共享数据
ThreadLocal 的构造方法和普通方法:
2.改进转账程序:
1.改写utils层JDBCUtils类中的获取数据库连接的方法:
//创建静态私有变量ThreadLocalprivate static ThreadLocal<Connection> local = new ThreadLocal<Connection>();//创建获取数据库连接的方法public static Connection getConnection() throws ClassNotFoundException, SQLException { Class.forName("com.mysql.jdbc.Driver"); try{ //从当前线程中获取连接对象 Connection connection = local.get(); //如果连接对象为空,则是第一次使用,调用DriverManager创建连接对象 if (connection == null){ connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/shop", "root", "123"); local.set(connection); } return connection; }catch (Exception e){ throw new RuntimeException(e); } }
2.OrderService
Connection connection = null; try { connection = JDBCUtils.getConnection(); connection.setAutoCommit(false); /**不再传递连接对象*/ orderDao.outMoney(name,money_int); orderDao.inMoney(to,money_int); connection.commit(); }
3.OrderDao
使用getConnection( )方法获取数据库连接
connection = JDBCUtils.getConnection();
- 【事务一】数据库事务
- 数据库事务
- 数据库事务
- 数据库事务
- 数据库事务
- 数据库事务
- 数据库事务
- 数据库事务
- 数据库事务
- 数据库事务
- 数据库事务
- 数据库事务
- 数据库事务
- 数据库事务
- 数据库事务
- 数据库事务
- 数据库事务
- 数据库事务
- 图像修补
- eos 项目不能部署到服务器
- 【STL】vector要点及使用
- JSP基础详解
- Python字符串capitalize()方法
- 数据库事务
- android 蓝牙sco开发
- 无责任共享 Coursera、Udacity 等课程视频【百度云】
- set集合练习
- PassNote隐私策略
- PAT乙级题1011.A+B和C
- java中常见的类、包、接口
- mysql事务和锁InnoDB
- C++深拷贝与浅拷贝