博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
事务实现原则(一) 事务的改变以及JDBC事务的设计
阅读量:6414 次
发布时间:2019-06-23

本文共 3392 字,大约阅读时间需要 11 分钟。

事务实现原则

事务:数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。事务是数据库运行中的逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。

随着计算机应用的告诉发展,伴随着大量业务系统的改造,从简单的单机到分布式应用的部属,事务一致性问题伴随发展,包括:

  • 数据并发访问、修改。   
  • 不同请求之间的数据隔离
  • 多个服务共同完成一个业务请求,保证都完成或者都失败
  • 发生异常时的数据回滚

举一个例子:张三给李四转账100元

这个操作必须是统一完成的,任何一方修改都不能完成事务的提交,否则造成数据不一致。

在传统的操作中大多数都是JDBC事务的操作:

之前在开发中使用的JDBC操作如下代码所示:

import java.sql.*;import java.util.LinkedList;import java.util.List;/** * JDBC辅助组件 * *  在代码中,是不能出现任何hard code(硬编码)的字符 * 比如“张三”、“com.mysql.jdbc.Driver” * 所有这些东西,都需要通过常量来封装和使用 *  *  * */public class JDBCHelper {        // 第一步:在静态代码块中,直接加载数据库的驱动    // 加载驱动,不是直接简单的,使用com.mysql.jdbc.Driver就可以了    // 之所以说,不要硬编码,他的原因就在于这里    //     // com.mysql.jdbc.Driver只代表了MySQL数据库的驱动    // 那么,如果有一天,我们的项目底层的数据库要进行迁移,比如迁移到Oracle    // 或者是DB2、SQLServer    // 那么,就必须很费劲的在代码中,找,找到硬编码了com.mysql.jdbc.Driver的地方,然后改成    // 其他数据库的驱动类的类名    // 所以正规项目,是不允许硬编码的,那样维护成本很高    //     // 通常,我们都是用一个常量接口中的某个常量,来代表一个值    // 然后在这个值改变的时候,只要改变常量接口中的常量对应的值就可以了    //     // 项目,要尽量做成可配置的    // 就是说,我们的这个数据库驱动,更进一步,也不只是放在常量接口中就可以了    // 最好的方式,是放在外部的配置文件中,跟代码彻底分离    // 常量接口中,只是包含了这个值对应的key的名字    static {        try {            String driver = ConfigurationManager.getProperty(Constants.JDBC_DRIVER);            Class.forName(driver);        } catch (Exception e) {            e.printStackTrace();          }    }        // 第二步,实现JDBCHelper的单例化    // 为什么要实现代理化呢?因为它的内部要封装一个简单的内部的数据库连接池    // 为了保证数据库连接池有且仅有一份,所以就通过单例的方式    // 保证JDBCHelper只有一个实例,实例中只有一份数据库连接池    private static JDBCHelper jdbcHelper = null ;    /**     * 获取单利     * @return     */    public static JDBCHelper getInstance(){        if(jdbcHelper  == null){            synchronized (JDBCHelper.class){                if(jdbcHelper == null)                    jdbcHelper = new JDBCHelper();            }        }        return  jdbcHelper;    }    // 创建数据库连接池    private LinkedList
datasource = new LinkedList
(); /** * 通过构造方法 :实现单例的过程中,创建唯一的数据库连接池 * 创建指定数量的连接池 */ private JDBCHelper(){ int datasourceLength = ConfigurationManager.getInteger("Constants.JDBC_DATASOURCE_SIZE"); for (int i=0;i
paramsList) { int[] rtn = null; Connection conn = null; PreparedStatement pstmt = null; try { conn = getConnection(); // 第一步:使用Connection对象,取消自动提交 conn.setAutoCommit(false); pstmt = conn.prepareStatement(sql); // 第二步:使用PreparedStatement.addBatch()方法加入批量的SQL参数 for(Object[] params : paramsList) { for(int i = 0; i < params.length; i++) { pstmt.setObject(i + 1, params[i]); } pstmt.addBatch(); } // 第三步:使用PreparedStatement.executeBatch()方法,执行批量的SQL语句 rtn = pstmt.executeBatch(); // 最后一步:使用Connection对象,提交批量的SQL语句 conn.commit(); } catch (Exception e) { e.printStackTrace(); } return rtn; } /** * 内部类,需要处理查询结果 */ public static interface QueryCallback{ /** * 处理查询结果 * @param rs * @throws Exception */ void process(ResultSet rs) throws Exception; }}

 

转载于:https://www.cnblogs.com/Tonyzczc/p/9989048.html

你可能感兴趣的文章
反射实现AOP动态代理模式(Spring AOP实现原理)
查看>>
Ant小总结
查看>>
Jetty 的工作原理以及与 Tomcat 的比较
查看>>
VMware-vSphere-5.1--------群集、HA、DRS、FT
查看>>
iOS导航栏的隐藏方式
查看>>
js复制
查看>>
JavaScript,只有你想不到
查看>>
Triangle
查看>>
web.xml 中元素加载顺序及其详解
查看>>
[原]浅谈几种服务器端模型——多线程并发式(线程池)
查看>>
tmux 常用快捷键
查看>>
linux下端口转发工具
查看>>
spring 中实现文件上传
查看>>
JAVA调用lp_solve配置详解
查看>>
BMP文件格式详解(BMP file format)
查看>>
25. [Microsoft][ODBC SQL Server Driver][DBNETLI...
查看>>
android开发过程中遇到错误的笔记
查看>>
JS实现继承的几种方式
查看>>
Spring MVC 4.x + fastjson 1.2.7,封装的List<?>参数
查看>>
svn培训
查看>>