`
kyo100900
  • 浏览: 637924 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JDBC的事务初探

阅读更多

很久没有更新Blog,有点惭愧啊,呵呵,其实我一直在懵懵懂懂的学习事务处理。Spring把这一切封装的很好了,以至于我现在都无法正常写出一个像样的JDBC事务处理的程序,如果让我用JDBC写语句,还是有很多ASP的影子。无意中买了10月的《程序员》杂志,没想到里面讲了SQL Server的事务处理,我耐着性子看完了,于是我想把它转换成实际的Java代码。呵呵,言归正传,开始我们今天的旅行吧。

首先,我的平台是WindowsXP2+JDK1.5+myeclispe6.0+mysql5.037。这个环境配置可能与大家不一样,请注意一下。先建一个数据库,我用的是MySQL自带的test,在里面随便建立了一个表格,结构如下,大家可以随便建立,不必过于在意,因为是初探,所以开始不会有很复杂的内容,而且东西也是越简单越好,呵呵。

sql 代码
  1. DROP TABLE IF EXISTS `tbl_tran`;   
  2. CREATE TABLE `tbl_tran` (   
  3.   `id` int(10) unsigned NOT NULL auto_increment,   
  4.   `namevarchar(45) NOT NULL,   
  5.   `age` int(10) unsigned NOT NULL,   
  6.   `gender` char(1) NOT NULL,   
  7.   `memo` text,   
  8.   PRIMARY KEY  (`id`)   
  9. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;  

 

建立好了表,可以往里加入一个测试数据比如:

sql 代码
  1. INSERT INTO `tbl_tran` VALUES (1,'leo',0,'M','hello leo');  

一切都准备好了。开始写测试代码啦。

java 代码
  1. package com.leo.tran;   
  2.   
  3. import java.sql.Connection;   
  4. import java.sql.ResultSet;   
  5. import java.sql.SQLException;   
  6. import java.sql.Statement;   
  7.   
  8. import com.leo.jdbc.DBConnection;   
  9.   
  10. public class TranJDBC1 {   
  11.   
  12.     private static Connection conn;   
  13.     private static Connection conn_two;   
  14.   
  15.     // 要测试的某条记录   
  16.     private static String testName = "leo";   
  17.   
  18.     // 要测试的这条记录更新的一个字段   
  19.     private static int testAge = 23;   
  20.   
  21.     /**  
  22.      * 初始化两个连接,不使用单例  
  23.      */  
  24.     static {   
  25.         conn = DBConnection.getConnection();   
  26.         conn_two = DBConnection.getConnection();   
  27.         try {   
  28.             conn_two.setAutoCommit(false);   
  29.         } catch (SQLException e) {   
  30.             e.printStackTrace();   
  31.         }   
  32.     }   
  33.   
  34.     /**  
  35.      * 默认的事物处理级别为4 也就是:TRANSACTION_REPEATABLE_READ,支持可重复读  
  36.      *   
  37.      * @param conn  
  38.      * @return  
  39.      * @throws SQLException  
  40.      */  
  41.     public static int getDefaultTransactionIsolation(Connection conn)   
  42.             throws SQLException {   
  43.         return conn.getTransactionIsolation();   
  44.     }   
  45.   
  46.     /**  
  47.      * 更新测试记录  
  48.      */  
  49.     public static void updateTable(int age) {   
  50.         Statement stmt = null;   
  51.         try {   
  52.             stmt = conn_two.createStatement();   
  53.             stmt.executeUpdate("update tbl_tran set age = " + age   
  54.                     + " where name = '" + testName + "'");   
  55.             System.out.println("[数据库开始更新中..............]");   
  56.         } catch (SQLException e) {   
  57.             try {   
  58.                 conn_two.close();   
  59.             } catch (SQLException e1) {   
  60.                 e1.printStackTrace();   
  61.             }   
  62.         }   
  63.     }   
  64.   
  65.     /**  
  66.      * 查询测试记录信息  
  67.      */  
  68.     public static void selectTable() {   
  69.         Statement stmt = null;   
  70.         try {   
  71.             stmt = conn.createStatement();   
  72.             String sql = "select * from tbl_tran where name = '" + testName   
  73.                     + "'";   
  74.             ResultSet rs = stmt.executeQuery(sql);   
  75.             while (rs.next()) {   
  76.                 System.out   
  77.                         .println("===========================打印输出开始===============================");   
  78.                 System.out.println("[ID为: " + rs.getInt("id") + "]");   
  79.                 System.out.println("[Name为: " + rs.getString("name") + "]");   
  80.                 System.out.println("[age为: " + rs.getString("age") + "]");   
  81.                 System.out.println("[gender为: " + rs.getString("gender") + "]");   
  82.                 System.out.println("[memo为: " + rs.getString("memo") + "]");   
  83.                 System.out   
  84.                         .println("===========================打印输出结束===============================");   
  85.             }   
  86.         } catch (SQLException e) {   
  87.             try {   
  88.                 conn.close();   
  89.             } catch (SQLException e1) {   
  90.                 e1.printStackTrace();   
  91.             }   
  92.         }   
  93.     }   
  94.   
  95.     /**  
  96.      * 使用默认的自动提交的Connection测试  
  97.      * @throws SQLException  
  98.      */  
  99.     public static void testTransaction() throws SQLException {   
  100.         System.out.println("[查看需要测试的记录原始信息.........]");   
  101.         System.out.println("[未更新前的详细信息.........]");   
  102.         selectTable();   
  103.         System.out.println("[为了测试先把查询的conn的事务设置成提交读.........]");   
  104.         // Transaction isolation level NONE not supported by MySQL   
  105.         conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);   
  106.         // 设置conn_two为默认提交   
  107.         conn_two.setAutoCommit(true);   
  108.         updateTable(testAge);   
  109.         System.out.println("[更新后,但事务自动提交后记录的详细信息.........]");   
  110.         selectTable();   
  111.     }   
  112.   
  113.     /**  
  114.      * 关闭默认自动提交的Connection测试  
  115.      * @throws SQLException  
  116.      */  
  117.     public static void testTransaction2() throws SQLException {   
  118.         System.out.println("[查看需要更新的记录信息.........]");   
  119.         System.out.println("[未更新前的详细信息.........]");   
  120.         selectTable();   
  121.         System.out.println("[为了测试先把查询的conn的事务设置成提交读.........]");   
  122.         // 注意:Transaction isolation level NONE not supported by MySQL   
  123.         conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);   
  124.         updateTable(testAge);   
  125.         System.out.println("[更新后,但事务尚未提交时记录的详细信息.........]");   
  126.         selectTable();   
  127.         // 提交那个更新的Connection,然后再查询数据库   
  128.         conn_two.commit();   
  129.         System.out.println("[更新后,但事务提交后记录的详细信息.........]");   
  130.         selectTable();   
  131.   
  132.     }   
  133.   
  134.     public static void main(String[] args) throws SQLException {   
  135.         System.out.println("[先看看Connection默认事务处理级别为: "  
  136.                 + getDefaultTransactionIsolation(conn) + " ]");   
  137.         System.out.println();   
  138.         testTransaction();   
  139.   
  140.     }   
  141.   
  142. }  

条码很简单,就是两个方法:

1.testTransaction():大家在使用Connection的时候,常常容易使用默认的连接,而这个连接是默认提交的,不具备事务处理的能力,所以在测试中,即使你已经设置了另一个Conn的隔离级别,但仍然不起作用,呵呵,我在刚开始编程ASP的时候,要处理关联表,不知道事务的概念,常常是一个表有数据了,另一个表出问题了,或者是插入一半数据了,然后手工改,慢慢接触了Java,使用了Spring,才知道事务的概念很重要。

2.testTransaction2():是正确的使用方法。一个连接在访问一条记录,另一个连接却想更新这条记录,那么应该看到什么样的结果呢?这个时候,隔离级别就起作用了,这里用的是READ_COMMITED,即提交读,也就是说没有提交过的记录是看不到的。只有更新的那个Conn_two提交了,或者是回滚了,也就是说Conn_two的事务结束了,才可以看到最后的结果。打印的结果是:

 

java 代码
  1. [数据库已打开...........................]   
  2. [数据库已打开...........................]   
  3. [先看看Connection默认事务处理级别为: 4 ]   
  4.   
  5. [查看需要更新的记录信息.........]   
  6. [未更新前的详细信息.........]   
  7. ===========================打印输出开始===============================   
  8. [ID为: 1]   
  9. [Name为: leo]   
  10. [age为: 0]   
  11. [gender为: M]   
  12. [memo为: hello leo]   
  13. ===========================打印输出结束===============================   
  14. [为了测试先把查询的conn的事务设置成提交读.........]   
  15. [数据库开始更新中..............]   
  16. [更新后,但事务尚未提交时记录的详细信息.........]   
  17. ===========================打印输出开始===============================   
  18. [ID为: 1]   
  19. [Name为: leo]   
  20. [age为: 0]   
  21. [gender为: M]   
  22. [memo为: hello leo]   
  23. ===========================打印输出结束===============================   
  24. [更新后,但事务提交后记录的详细信息.........]   
  25. ===========================打印输出开始===============================   
  26. [ID为: 1]   
  27. [Name为: leo]   
  28. [age为: 23]   
  29. [gender为: M]   
  30. [memo为: hello leo]   
  31. ===========================打印输出结束===============================   

 

我的main()方法,测试的是testTransaction2(),而testTransaction()大家也可测试一下,了解有时候默认的配置并不是最合适的选择。这个主题还会继续补充的,今天先到这里吧。

分享到:
评论

相关推荐

    JOTM 分布式事务初探(JNDI,Tomcat 7 JDBC Pool连接池)

    NULL 博文链接:https://jackyin5918.iteye.com/blog/1922379

    Sharding生态圈初探.pptx

    Sharding-JDBC是Sharding生态圈的基础组件,它的主要能力包括:配置中心、熔断机制、Opentracing支持、异步补偿型事务、负载均衡、同线程数据一致性以及透明化的分布式SQL处理。通过将数据读写分片分离,Sharding-...

    ejb3 jpa初探

    JPA允许开发者使用面向对象的编程模型来操作关系数据库,消除了传统的JDBC和SQL代码,提高了代码的可读性和可维护性。JPA通过实体(Entity)、实体管理器(EntityManager)和实体管理工厂(EntityManagerFactory)等...

    spring+mybatis初探

    MyBatis则是一个轻量级的ORM(Object-Relational Mapping)框架,它解决了在Java中操作数据库的传统JDBC的繁琐。MyBatis通过XML或注解的方式将SQL语句与Java代码分离,简化了数据库操作,同时保留了对SQL的直接控制...

    pring初探共18页.pdf.zip

    4. **AOP**:介绍什么是切面,切点,通知,连接点等概念,以及如何在Spring中实现AOP来实现横切关注点,如日志记录、事务管理等。 5. **Spring MVC**:Spring用于Web开发的部分,解释Model-View-Controller模式,...

    spring 初探

    标题中的“spring 初探”表明我们即将探讨的是Spring框架的基础知识。Spring是Java企业级应用开发中最常用的一个开源框架,由Rod Johnson发起,旨在简化应用程序的开发,提高组件之间的解耦。 首先,Spring框架的...

    spring in action 最新

    在DAO层面,书中涵盖了与数据库交互的各种策略,包括JDBC、Hibernate和MyBatis等ORM工具的集成。 在事务管理方面,读者将学习到Spring提供的声明式和编程式事务管理机制,这使得事务控制变得简单而直观。此外,书中...

    spring-framework-0.9.1.zip

    《Spring Framework 0.9.1:初探与解析》 Spring Framework,作为Java开发领域中的一个里程碑式框架,自其诞生以来就以其强大的企业级应用支持和灵活的编程模式深受开发者喜爱。本文将深入探讨Spring Framework ...

    Servlet与JSP核心编程第2版

    1.3 servlet代码初探 1.4 servlet相对于“传统”cgi的优点 1.5 jsp的作用 第1部分 servlet技术 第2章 服务器的安装和配置 2.1 下载和安装java软件开发工具包 2.2 为桌面计算机下载服务器 2.3 服务器的...

    spring 课件下载

    1. **Spring初探** 在这一章中,我们将从Spring框架的基础出发,介绍其诞生背景和主要目标。我们会讲解Spring如何简化Java应用的开发,以及它提供的依赖注入(Dependency Injection, DI)机制,这是Spring的核心...

    入门java web项目 高校马拉松

    【Java Web项目初探:高校马拉松】 在信息技术领域,Java Web技术是开发互联网应用程序的主流之一,尤其在教育环境中,如“高校马拉松”这样的项目,它通常被用来培养学生的编程能力和团队协作精神。Java Web项目...

    hibernate3.3.2jar包part1

    《Hibernate 3.3.2:Java对象持久化框架初探》 Hibernate,作为一个流行的开源对象关系映射(ORM)框架,为Java开发者提供了一种简单而强大的方式来管理数据库操作。在Java应用中,Hibernate使得开发人员可以将业务...

    2.spring_beginning

    《Spring框架初探》 Spring框架是Java企业级应用开发中的重要组成部分,它以其轻量级、模块化和全面的特性赢得了广大开发者喜爱。本文将深入探讨Spring框架的基础知识,帮助初学者理解并掌握这一强大的工具。 首先...

Global site tag (gtag.js) - Google Analytics