JDBC编程-事务编程(四)

事务的概念

事务的概念在我看来是指的是一组sql序列,这个序列是一块执行的单位,要么全部执行,要不全部执行,这样可以很好的对数据库进行并发控制。

因为数据库是多个用户都可以同时操作的,如果多个用户同时操作一个数据,就容易造成数据的不一致,所以事务作为并发控制的一个基本单位很有必要。

事务的特性

1.原子性:事务是一个完整的整体,所有的操作和数据都是一个整体。

2.一致性:事务的操作是一致性的。

3.隔离性:事务之间的操作是相互隔离的。

4.持久性:事务的操作是持久的,即使出现了错误也会完成。

事务的语句

BEGIN TRANSACTION

COMMIT TRANSACTION

ROLLBACK TRANSACTION

试验代码

public static Statement getStatement(){
        Statement st = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            Connection conn = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/jsp_dbb", "root", "");
            st = (Statement) conn.createStatement();
        } catch (Exception e) {
            // TODO: handle exception
        }
        return st;
    }
    public static void insertUserData(){
        try {
            String sql = "INSERT INTO tbl_user(id,name,password,email)" +
                    "VALUES(10,‘Tom‘,‘123456‘,‘[email protected]‘)";
            Statement st = getStatement();
            int count = st.executeUpdate(sql);
            System.out.println("插入了"+count+"行用户数据");
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }
    public static void insertAddressData(){
        try {
            String sql = "INSERT INTO tbl_address(id,city,country,user_id)" +
                    "VALUES(1,‘shanghai‘,‘china,‘10‘)";
            Statement st = getStatement();
            int count = st.executeUpdate(sql);
            System.out.println("插入了"+count+"行地址数据");
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        insertUserData();
        insertAddressData();
    }

这段代码会报错,因为在tbl_address中已经有id = 1的数据了,具体如下图:

插入了1行用户数据
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘10‘)‘ at line 1
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:377)
    at com.mysql.jdbc.Util.getInstance(Util.java:360)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:978)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3887)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3823)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2435)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2582)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2526)
    at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1618)
    at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1549)
    at liu.peng.jdbc.TransactionTest.insertAddressData(TransactionTest.java:37)
    at liu.peng.jdbc.TransactionTest.main(TransactionTest.java:46)

检查发现只是插入user表的数据,没有插入address表数据,造成数据不完整。

事务处理的应用

事务处理的核心代码就是

conn.setAutoCommit(false);

在执行完之后的提交。

conn.commit();

以及在捕获异常时候的回滚。

具体代码如下:

public static Connection getConnection(){
        Connection conn = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/jsp_dbb", "root", "");
        } catch (Exception e) {
            // TODO: handle exception
        }
        return conn;
    }
    public static void insertUserData(Connection conn)throws SQLException{
            String sql = "INSERT INTO tbl_user(id,name,password,email)" +
                    "VALUES(10,‘Tom‘,‘123456‘,‘[email protected]‘)";
            Statement st = (Statement) conn.createStatement();
            int count = st.executeUpdate(sql);
            System.out.println("插入了"+count+"行用户数据");
    }
    public static void insertAddressData(Connection conn) throws SQLException{
            String sql = "INSERT INTO tbl_address(id,city,country,user_id)" +
                    "VALUES(1,‘shanghai‘,‘china,‘10‘)";
            Statement st = (Statement) conn.createStatement();
            int count = st.executeUpdate(sql);
            System.out.println("插入了"+count+"行地址数据");
    }
    public static void main(String[] args) {
        Connection conn = null;
        try {
            conn = getConnection();
            conn.setAutoCommit(false);
            insertUserData(conn);
            insertAddressData(conn);
            conn.commit();
        } catch (SQLException e) {
            System.out.println("==========捕获SQL异常=========");
            e.printStackTrace();
            try {
                conn.rollback();
                System.out.println("=======s事务回滚成功=======");
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }finally{
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (Exception e3) {
                e3.printStackTrace();
            }
        }
    }

Console界面的报错信息为:

插入了1行用户数据
==========捕获SQL异常=========
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘10‘)‘ at line 1
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:377)
    at com.mysql.jdbc.Util.getInstance(Util.java:360)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:978)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3887)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3823)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2435)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2582)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2526)
    at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1618)
    at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1549)
    at liu.peng.jdbc.TransactionTest.insertAddressData(TransactionTest.java:31)
    at liu.peng.jdbc.TransactionTest.main(TransactionTest.java:40)
=======s事务回滚成功=======

证明两条数据都没有插入进去保证了数据的完整性,而第一次只是插入user表的数据,没有插入address表数据,造成数据不完整。

时间: 2024-10-12 01:17:04

JDBC编程-事务编程(四)的相关文章

C#编程总结(四)多线程应用

C#编程总结(四)多线程应用 多线程应用很广泛,简单总结了一下: 1)不阻断主线程,实现即时响应,由后台线程完成特定操作2)多个线程,完成同类任务,提高并发性能3)一个任务有多个独立的步骤,多个线程并发执行各子任务,提高任务处理效率 下面我们通过几个小例子做简单介绍. 1.进度条 分析:页面动态刷新,主页面正常可操作.我们通过后台线程来实现进度条. 首先,创建Winform页面,然后拖入进度条控件,将页面的代码改为以下代码即可. 这里只是个简单的例子,其实我们可以做的更好,将进度条封装为一个自定

线程同步-iOS多线程编程指南(四)-08-多线程

首页 编程指南 Grand Central Dispatch 基本概念 多核心的性能 Dispatch Sources 完结 外传:dispatch_once(上) Block非官方编程指南 基础 内存管理 揭开神秘面纱(上) 揭开神秘面纱(下) iOS多线程编程指南 关于多线程编程 线程管理 Run Loop 线程同步 附录 Core Animation编程指南 Core Animation简介 基本概念 渲染架构 几何变换 查看目录 中文手册/API ASIHTTPRequest Openg

java编程思想第四版中net.mindview.util包下载,及源码简单导入使用

在java编程思想第四版中需要使用net.mindview.util包,大家可以直接到http://www.mindviewinc.com/TIJ4/CodeInstructions.html 去下载,并按照所在页面的操作进行操作.当然也可以直接我下载下面的链接,下载的直接是JAR包,可以直接导入并使用: net.mindview.util包:百度网盘:点击下载  密码: ggpi java编程思想第四版源码:百度网盘:点击下载  密码: ur3e 下面我简单的介绍一下源码在Eclipse中的导

[C# 网络编程系列]专题四:自定义Web浏览器

转自:http://www.cnblogs.com/zhili/archive/2012/08/24/WebBrowser.html 前言: 前一个专题介绍了自定义的Web服务器,然而向Web服务器发出请求的正是本专题要介绍的Web浏览器,本专题通过简单自定义一个Web浏览器来简单介绍浏览器的工作原理,以及帮助一些初学者揭开浏览器这层神秘的面纱(以前总感觉这些应用感觉很深奥的,没想到自己也可以自定义一个浏览器出来),下面不啰嗦了,进入正题. 一.Web浏览器的介绍 Web浏览器是指可以显示Web

linux系统编程之信号(四)

今天继续探讨信号相关的东东,话不多说,正入正题: 信号在内核中的表示: 下面用图来进一步描述这种信号从产生到递达之间的状态(信号阻塞与未诀): 那是怎么来决定的呢?下面慢慢来举例分解: 所以,通过这些图,可以描述信号从产生到递达的一个过程,上面的理解起来可能有点难,下面会用代码来进一步阐述,在进行实验之前,还需了解一些函数的使用,这些函数在实验中都会被用到,也就是信号集操作函数. 信号集操作函数: 其中解释一下sigset_t,百度百科解释为: 而这个函数的意义就是将这64位清0 这个函数的意义

ActionScript3游戏中的图像编程(连载四十六)

总目录:http://blog.csdn.net/iloveas2014/article/details/38304477 3.1.2 以小见大--从细节损失洞悉滤镜本质 把它再改回内斜角,边缘似乎光滑了些,但这种错觉仅仅是由于阴影与蓝色的对比度不够强烈,才会让边缘的粗糙不够显眼.把文字颜色调成浅紫以后,转角处的锯齿依旧一览无余.(图 3.6),而Photoshop应用同样的设置则不会出现同样的问题(图 3.7). 图 3.6 模糊值为3的内侧斜角滤镜 图 3.7 大小等于3的斜面样式 如果认为

Java编程思想第四版读书笔记——第十三章 字符串

Java编程思想第四版读书笔记--第十三章 字符串 字符串的操作是计算机程序设计中最常见的行为. 关键词: StringBuilder ,StringBuffer,toString(),format转换,正则表达式, 1.不可变String String对象时不可变的.每当把String对象作为方法的参数时,都会复制一份引用.(其实就是对函数中参数列表中参数的操作不会影响外面的原参数) 如下: import static net.mindview.util.Print.*; public cla

ActionScript3游戏中的图像编程(连载四十七)

总目录:http://blog.csdn.net/iloveas2014/article/details/38304477 3.1.3 用内侧滤镜验证Flash简单滤镜的实现原理 以上测试都在外侧进行,为了证实内侧滤镜的实现机制与外侧并无大异,我再次用一个方块让内阴影滤镜在方块上移动.(图 3.23) 图 3.23 内阴影滤镜的效果 阴影层似乎并非从复制出来的轮廓,因为方块的边缘并不存在这种内转角的结构.但是,当我把距离调回到0的时候,真相终于浮出水面.(图 3.24) 图 3.24 距离为0的

ActionScript3游戏中的图像编程(连载四十八)

总目录:http://blog.csdn.net/iloveas2014/article/details/38304477 3.1.4 简单滤镜中的渐变原理探讨 我们再简单的看一下滤镜里的渐变条. 为了尽可能地减少复杂的文字轮廓所造成的干扰,我再次使用方块进行试验. 我画了一个紫色的方块(啥颜色其实都无所谓了),然后添加渐变发光滤镜,把模糊和距离值都调大,以便看清楚渐变的轮廓,然后给渐变条随意地加上几种颜色(图 3.30) 图 3.30 模糊范围较大的渐变发光 可以看到,渐变条上的色彩从右往左地