`

JDBC事务处理

    博客分类:
  • Jdbc
阅读更多
1. 事务的概念

事务处理在数据库开发中有着非常重要的作用,所谓事务就是所有的操作要么一起成功,要么一起失败,事务本身具有原子性(Atomicity)、一致性(Consistency)、隔离性或独立性(Isolation)、持久性(Durability)4个特性,这4个特性也被称为ACID特征。

原子性:原子性是事务最小的单元,是不可再分隔的单元,相当于一个个小的数据库操作,这些操作必须同时成功,如果一个失败了,则一切的操作将全部失败。

一致性:指的是在数据库操作的前后是完全一致的,保证数据的有效性,如果事务正常操作则系统会维持有效性,如果事务出现了错误,则回到最原始状态,也要维持其有效性,这样保证事务开始时和结束时系统处于一致状态。

隔离性:多个事务可以同时进行且彼此之间无法访问,只有当事务完成最终操作时,才可以看到结果。

持久性:事务完成之后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将一直保持。


2. MySQL对事务的支持

序号 命令 描述
1 SET AUTOCOMMIT=0    取消自动提交处理,开启事务处理
2 SET AUTOCOMMIT=1    打开自动提交处理,关闭事务处理
3 START TRANSACTION    启动事务
4 BEGIN    启动事务,相当于执行 START TRANSACTION
5 COMMIT    提交事务
6 ROLLBACK    回滚全部事务
7 SAVEPOINT 事务保存点名称    设置事务保存点
8 ROLLBACK TO SAVEPOINT 保存点名称    回滚操作到保存点


3. JDBC事务处理

4. 事务保存点

create table t_account (
  id int(11) not null auto_increment,
  accountname varchar(20) default null,
  accountbalance int(11) default null,
  primary key (id)
) engine=innodb auto_increment=3 default charset=utf8;

insert into t_account(id,accountName,accountBalance) values (1,'张三',500),(2,'李四',1000);

Demo01.java

package com.andrew.jdbc.chap09;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import com.andrew.jdbc.util.DbUtil;

public class Demo01 {
    private static DbUtil dbUtil = new DbUtil();

    // 转出
    private static void outCount(Connection con, String accountName, int account) throws Exception {
        String sql = "update t_account set accountBalance=accountBalance-? where accountName=?";
        PreparedStatement pstmt = con.prepareStatement(sql);
        pstmt.setInt(1, account);
        pstmt.setString(2, accountName);
        pstmt.executeUpdate();
    }

    // 转入
    private static void inCount(Connection con, String accountName, int account) throws Exception {
        String sql = "update t_account set accountBalance=accountBalance+? where accountName=?";
        PreparedStatement pstmt = con.prepareStatement(sql);
        pstmt.setInt(1, account);
        pstmt.setString(2, accountName);
        pstmt.executeUpdate();
    }

    public static void main(String[] args) {
        Connection connection = null;
        try {
            connection = dbUtil.getConnection();
            connection.setAutoCommit(false); // 取消自动提交
            System.out.println("张三开始向李四转账!");
            int account = 500;
            outCount(connection, "张三", account);
            inCount(connection, "李四", account);
            System.out.println("转账成功!");
        } catch (Exception e) {
            try {
                connection.rollback(); // 回滚
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            try {
                connection.commit(); // 提交事务
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

张三开始向李四转账!
转账成功!
500 1000 ->
0 1500
如果修改sql语句报错则不能执行


Demo02.java

package com.andrew.jdbc.chap09;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Savepoint;

import com.andrew.jdbc.util.DbUtil;

public class Demo02 {
    private static DbUtil dbUtil = new DbUtil();

    // 转出
    private static void outCount(Connection con, String accountName, int account) throws Exception {
        String sql = "update t_account set accountBalance=accountBalance-? where accountName=?";
        PreparedStatement pstmt = con.prepareStatement(sql);
        pstmt.setInt(1, account);
        pstmt.setString(2, accountName);
        pstmt.executeUpdate();
    }

    // 转入
    private static void inCount(Connection con, String accountName, int account) throws Exception {
        String sql = "update t_account set account=accountBalance+? where accountName=?";
        PreparedStatement pstmt = con.prepareStatement(sql);
        pstmt.setInt(1, account);
        pstmt.setString(2, accountName);
        pstmt.executeUpdate();
    }

    public static void main(String[] args) {
        Connection connection = null;
        Savepoint savepoint = null;
        try {
            connection = dbUtil.getConnection();
            connection.setAutoCommit(false); // 取消自动提交
            System.out.println("张三开始向李四转账!");
            int account = 500;
            outCount(connection, "张三", account);
            savepoint = connection.setSavepoint(); // 设置一个保存点
            inCount(connection, "李四", account);
            System.out.println("转账成功!");
        } catch (Exception e) {
            try {
                connection.rollback(savepoint); // 回滚到savepoint保存点
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            try {
                connection.commit(); // 提交事务
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

运行结果:
张三开始向李四转账!
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'account' in 'field list'
500 1000 ->
0 1000
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics