当前位置:   article > 正文

JAVA互联网架构学习之批处理与编程性事务_java互联网架构学习之page分页?

java互联网架构学习之page分页?
批处理(batch)------------>好比快递员【不能一件一件的送快递】
- 批处理指的是一次操作中执行多条SQL语句
- 批处理相比于一次一次执行效率会提高很多

- 批处理主要是分两步:
1.将要执行的SQL语句保存
2.执行SQL语句

- Statement和PreparedStatement都支持批处理操作,这里我们只需要掌握PreparedStatement的批处理方式:
- 方法:
void addBatch()
- 将要执行的SQL先保存起来,先不执行
- 这个方法在设置完所有的占位符之后调用
int[] executeBatch()
- 这个方法用来执行SQL语句,这个方法会将批处理中所有SQL语句执行

- mysql默认批处理是关闭的,所以我们还需要去打开mysql的批处理:
rewriteBatchedStatements=true
我们需要将以上的参数添加到mysql的url地址中

- 注意:低版本的mysql-jdbc驱动也不支持批处理,一般都是在修改的时候使用批处理,查询的时候不使用!
5.1.7可用


案例演示:
1.创建一张新的数据表
CREATE TABLE BatchTest(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(50)
)
2.反复打开数据库客户端,插入语句【相当于每次获取一个connection连接,执行executeUpdate语句】
INSERT INTO t_emp(NAME) VALUES('张三');
SELECT * FROM t_emp;

3.引出批处理--->执行效率高,资源利用率好!
  1. @Test
  2. public void test() {
  3. Connection con = null;
  4. PreparedStatement ps=null;
  5. String sql="INSERT INTO BatchTest(`name`) VALUES (?)";
  6. //没配置批处理共花费时间:61210
  7. //打开批处理共花费时间:177
  8. try {
  9. con=JDBCUtil.getConnection();
  10. ps=con.prepareStatement(sql);
  11. //创建一个for循环,来设置占位符
  12. for (int i = 0; i < 1000; i++) {
  13. ps.setString(1, "test"+i);
  14. //添加到批处理方法中,调用无参的,有参的是Statement来调用的!
  15. ps.addBatch();
  16. }
  17. //获取一个时间戳
  18. long start=System.currentTimeMillis();
  19. //执行批处理
  20. ps.executeBatch();
  21. //获取一个时间戳
  22. long end=System.currentTimeMillis();
  23. System.out.println("共花费时间:"+(end-start));
  24. } catch (SQLException e) {
  25. e.printStackTrace();
  26. }finally {
  27. JDBCUtil.close(con, ps);
  28. }
  29. }






事务(Transaction)



演示银行转账的功能:
 1.创建一张表示账号的表
CREATE TABLE trade(
name VARCHAR(50) primary key,
money DECIMAL(11,2)
)

 2.向表中插入几个用户
INSERT INTO t_account(name,money) VALUES(sunwukong',1000);
INSERT INTO t_account(name,money) VALUES(zhubajie',1000);



 3.#sunwukong向shaheshang转账100元  
#从sunwukong的账号减去100元
UPDATE trade SET money= money - 100 WHERE name='sunwukong';


#给shaheshang的账号加上100元
UPDATE trade SET money = money+100 WHERE name = 'zhubajie';
 
 
    重新设置为1000元:
UPDATE trade SET money=1000;

 4.从java代码中演示上面的案例:
    1.创建Dao类
  1. public class AcountDao {
  2. public void update(Connection conn,String name,double money) {
  3. PreparedStatement ps=null;
  4. String sql = "update trade set money = money + ? where name = ?";
  5. try {
  6. ps = conn.prepareStatement(sql);
  7. ps.setInt(1, money);
  8. ps.setString(2, name);
  9. ps.execute();
  10. } catch (SQLException e) {
  11. // TODO Auto-generated catch block
  12. e.printStackTrace();
  13. }finally {
  14. JDBCUtil.close(null, ps);
  15. }
  16. }
  17. }



2.测试该DAO
  1. public class TestTransaction {
  2. private AcountDao dao = new AcountDao();
  3. @Test
  4. public void test() {
  5. //从sunwukong账户向shaheshang账户转账100元!
  6. //1.从sunwukong账户扣除100元
  7. dao.update("sunwukong", -100);
  8. //2.向shaheshang账户添加100元
  9. dao.update("shaheshang", 100);
  10. }
  11. }


//显然上面是可以正常执行的!
但是如果上面的程序在suwukong减去100元之后,shaheshang加钱之前,出现了异常,如下所示:

  1. //从sunwukong账户向shaheshang账户转账100元!
  2. //1.从sunwukong账户扣除100元
  3. accountDao.update("sunwukong", -100);
  4. int i =10/0;//添加一个异常
  5. //2.向shaheshang账户添加100元
  6. accountDao.update("shaheshang", 100);




- 在开发中我们的一个业务往往需要同时操作多个表,这些操作往往是不可分割,业务中的对数据库的多次操作,
 要么同时成功,要么全都失败。



- 事务的特性(ACID):
原子性(atomicity)
一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。

一致性(consistency)
事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。


隔离性(isolation)
一个事务的执行不能被其他事务干扰。
即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

持久性(durability)
持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。
接下来的其他操作或故障不应该对其有任何影响。

- 操作事务的基本步骤:
1.开启事务
- 开启事务以后,我们只后的所有操作将都会在同一个事务当中
2.操作数据库
- 开启事务以后再去操作数据库,所有操作将不会直接提交到数据库中
3.提交事务
- 将修改应用到数据库
4.回滚事务
- 数据库操作过程中出现异常了,回滚事务,回滚事务以后,数据库变成开启事务之前的状态

- mysql中的事务控制
#开启事务
START TRANSACTION
#回滚事务
ROLLBACK
#提交事务
COMMIT

- JDBC中的事务主要通过Connection对象来控制的
1.开启事务
void setAutoCommit(boolean autoCommit) throws SQLException;
- 设置事务是否自动提交,默认是自动提交
- 设置事务手动提交
conn.setAutoCommit(false);

2.提交事务
void commit() throws SQLException;
- 提交事务
conn.commit()

3.回滚事务
void rollback() throws SQLException;
- 回滚事务
conn.rollback()

- 事务控制的格式:

  1. //创建一个Connection
  2. Connection conn = null;
  3. try{
  4. //获取Connection
  5. conn = JDBCUtils.getConnection();
  6. //开启事务
  7. conn.setAutoCommit(false);
  8. //对数据库进行操作
  9. //操作成功,提交事务
  10. conn.commit();
  11. }catch(Exception e){
  12. e.printStackTrace();
  13. //回滚事务
  14. try {
  15. conn.rollback();
  16. } catch (SQLException e1) {
  17. e1.printStackTrace();
  18. }
  19. }finally{
  20. JDBCUtils.close(conn, null, null);
  21. }


- 注意:我们在同一个事务中使用的数据库连接(Connection)必须是同一个,否则事务还是不作用!
所以此时原来的AcountDAO中的update方法要改为如下所示:

  1. public class AcountDao {
  2. public void update(Connection conn,String name,double money){
  3. //准备两个变量
  4. PreparedStatement ps = null;
  5. //准备SQL模板
  6. String sql = "UPDATE trade SET money = money + ? WHERE name = ?";
  7. try {
  8. //获取PreparedStatement
  9. ps = conn.prepareStatement(sql);
  10. //填充占位符
  11. ps.setDouble(1, money);
  12. ps.setString(2, name);
  13. //执行SQL语句
  14. ps.executeUpdate();
  15. } catch (SQLException e) {
  16. // TODO Auto-generated catch block
  17. e.printStackTrace();
  18. }finally{
  19. //此时也不能在这里关闭数据库连接了,而是在外边统一关闭
  20. JDBCUtil.close(null, ps, null);
  21. }
  22. }
  23. }

实际开发中我们一般将批处理和事务连用

  1. @Test
  2. public void testTranscateandButch() {
  3. Connection con=null;
  4. PreparedStatement ps=null;
  5. String sql="INSERT INTO BatchTest(`name`) VALUES (?)";
  6. //事务结合批处理共花费时间:19
  7. try {
  8. con=JDBCUtil.getConnection();
  9. con.setAutoCommit(false);
  10. ps=con.prepareStatement(sql);
  11. for (int i = 0; i < 1000; i++) {
  12. ps.setString(1, "test"+i);
  13. ps.addBatch();
  14. }
  15. long start=System.currentTimeMillis();
  16. ps.executeBatch();
  17. long end=System.currentTimeMillis();
  18. System.out.println("共花费时间:"+(end-start));
  19. con.commit();
  20. } catch (Exception e) {
  21. // TODO: handle exception
  22. System.out.println(e.getMessage());
  23. try {
  24. con.rollback();
  25. } catch (SQLException e1) {
  26. // TODO Auto-generated catch block
  27. e1.printStackTrace();
  28. }
  29. }finally {
  30. JDBCUtil.close(con, null);
  31. }
  32. }


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/程序质量控制师/article/detail/61812
推荐阅读
相关标签
  

闽ICP备14008679号