事务-Transaction

某些情况下我们希望对数据库的某一操作要么整体成功,要么整体失败,经典的例子就是支付宝提现。例如我们发起了支付宝到银行卡的100元提现申请,我们希望的结果是支付宝余额减少100元,银行卡余额增加100元,而不是支付宝的100元被扣除,而银行卡的100元却没收到。也就是说,要么100元从支付宝扣除的同时银行卡也会多出一百元,要么这次提现失败支付宝的100元还在,银行卡也没有收到钱。支付宝扣钱和银行卡收钱,这两件事要么都成功要么都失败。

事物的ACID特性:

满足ACID特性的操作,我们可以说它是一个事物。

  1. 原子性:该操作是最小逻辑单元整体,已经不可分隔。
  2. 一致性:要么所有都执行,要么所有都不执行。
  3. 隔离性:多个事务相互隔离,互不影响。
  4. 持久性:事物的执行结果永久生效。

对事物的控制:

在JDBC中可以调用Connection对象的setAutoCommit(false)这个接口,将commit()之前的所有操作都看成是一个事物。同时,如果事务执行过程中发生异常,可以调用rollback()接口进行回滚到事务开始之前的状态。

示例代码:

下面代码演示了将cjk的100元转账到ly的账户上:

package org.lyk.main;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import org.apache.commons.dbcp2.BasicDataSource;

public class Main

{

public static String DBDRIVER = "com.mysql.jdbc.Driver";

public static String DB_URL = "jdbc:mysql://localhost:3306/mldn";

public static String USERNAME = "root";

public static String PASSWORD = "admin";

public static BasicDataSource bds = null;

public static void main(String[] args)

{

dbPoolInit();

transferAmount();

System.out.println("///Done~~~");

}

public static void dbPoolInit()

{

bds = new BasicDataSource();

bds.setDriverClassName(DBDRIVER);

bds.setUrl(DB_URL);

bds.setUsername(USERNAME);

bds.setPassword(PASSWORD);

}

public static boolean transferAmount()

{

boolean retVal = true;

String sql = "UPDATE user SET amount=? WHERE userid=?";

Connection conn = null;

PreparedStatement stmt = null;

ResultSet rs = null;

try

{

conn = bds.getConnection();

conn.setAutoCommit(false);

stmt = conn.prepareStatement(sql);

stmt.setInt(1, 0);

stmt.setString(2, "cjk");

stmt.execute();

stmt.setInt(1, 100);

stmt.setString(2, "ly");

stmt.execute();

conn.commit();

} catch (SQLException e)

{

// TODO Auto-generated catch block

e.printStackTrace();

try

{

conn.rollback();

} catch (SQLException e1)

{

// TODO Auto-generated catch block

e1.printStackTrace();

}

}

finally

{

try

{

if(conn != null)

conn.close();

if(stmt != null)

stmt.close();

if(rs != null)

rs.close();

}

catch(Exception e)

{

//ignore all exceptions when closing...

}

}

return retVal;

}

}

事务断点(Savepoint):

某些时候,我们对一个事物操作失败,我们并不像回滚到最初状态,而是回滚到事务开始后的某一个地方,这时我们可以使用断点的方式让事物回滚到指定的断点(Savepoint)上.

示例代码:

下面的代码演示了如果cjk的100元转账到ly失败的话,我们将这100元转到cyx的账户上。(其中用手动跑出异常的方式模拟cjk到ly的转账失败)

package org.lyk.main;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Savepoint;

import org.apache.commons.dbcp2.BasicDataSource;

public class Main

{

public static String DBDRIVER = "com.mysql.jdbc.Driver";

public static String DB_URL = "jdbc:mysql://localhost:3306/mldn";

public static String USERNAME = "root";

public static String PASSWORD = "admin";

public static BasicDataSource bds = null;

public static void main(String[] args)

{

dbPoolInit();

transferAmount();

System.out.println("///Done~~~");

}

public static void dbPoolInit()

{

bds = new BasicDataSource();

bds.setDriverClassName(DBDRIVER);

bds.setUrl(DB_URL);

bds.setUsername(USERNAME);

bds.setPassword(PASSWORD);

}

public static boolean transferAmount()

{

boolean retVal = true;

String sql = "UPDATE user SET amount=? WHERE userid=?";

Connection conn = null;

PreparedStatement stmt = null;

ResultSet rs = null;

Savepoint sp = null;

try

{

conn = bds.getConnection();

conn.setAutoCommit(false);

stmt = conn.prepareStatement(sql);

stmt.setInt(1, 0);

stmt.setString(2, "cjk");

stmt.execute();

sp = conn.setSavepoint();

stmt.setInt(1, 100);

stmt.setString(2, "ly");

stmt.execute();

throw new Exception();

}

catch (Exception e)

{

e.printStackTrace();

try

{

conn.rollback(sp);

stmt.setInt(1, 100);

stmt.setString(2, "cyx");

stmt.execute();

conn.commit();

} catch (SQLException e1)

{

// TODO Auto-generated catch block

e1.printStackTrace();

}

}

finally

{

try

{

if(conn != null)

conn.close();

if(stmt != null)

stmt.close();

if(rs != null)

rs.close();

}

catch(Exception e)

{

//ignore all exceptions when closing...

}

}

return retVal;

}

}

JDBC中的事务-Transaction的更多相关文章

  1. 一、DAO设计模式 二、DAO设计模式的优化 三、JDBC中的事务,连接池的使用

    一.DAO设计模式概述###<1>概念 DAO,Data Access Object ,用于访问数据库的对象. 位于业务逻辑和数据持久化层之间,实现对数据持久化层的访问![](1.png) ...

  2. JDBC中处理事务,小Demo

    事务的四大特性(ACID):  原子性(Atomicity):事务中所有操作是不可再分割的原子单位.事务中所有操作要么全部执行成功,要么全部执行失败.  一致性(Consistency):事务执行 ...

  3. JDBC 中的事务和批处理 batch

    JDBC事务处理: 事务处理一般在事务开始前把事务提交设置为false 所有DML语句执行完成后提交事务 demo: package com.xzlf.jdbc; import java.sql.Co ...

  4. JDBC中DAO事务函数模版

    DAO事物函数模版1: public void OrderFinsByPage(){ Connection conn = null; PreparedStatement pstmt = null; R ...

  5. day18 8.jdbc中设置事务隔离级别

    设置数据库事务隔离级别特殊需求才有,后面很少用.因为数据库本身是事务隔离级别的,mysql的事务隔离级别是Repeatable read,可以解决脏读和不可重复读.不用设置,人家数据库是有事务隔离级别 ...

  6. Java数据库连接——JDBC调用存储过程,事务管理和高级应用

    一.JDBC常用的API深入详解及存储过程的调用 相关链接:Jdbc调用存储过程 1.存储过程(Stored Procedure)的介绍 我们常用的操作数据库语言SQL语句在执行的时候需要先编译,然后 ...

  7. java中对事务的理解

    一.什么是事务 事务是访问数据库的一个操作序列,数据库应用系统通过事务集来完成对数据库的存取. 二.事务的原则(ACID) 原子性:事务要么全部都被执行,要么就全都不被执行,如果有子事务提交失败,那么 ...

  8. Java中的事务及使用

    什么是事务? 事务(Transaction),一般是指要做的或所做的事情.在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit).事务通常由高级数据库操纵语言或编程语言(如S ...

  9. JDBC&&c3p0、事务、批处理、多线程 于一体的经典秘方QueryRunner

    目录: 基础篇_功能各自回顾 JDBC基础代码回顾(使用JdbcUtils工具简化) c3p0数据库连接池的使用(使用JdbcUtils工具简化) 大数据的插入(使用c3p0+JdbcUtils工具简 ...

随机推荐

  1. ABBYY导出结果为PDF注意事项

    使用ABBYY FineReader Pro for Mac OCR文字识别软件识别文档时,可以将已识别的文本保存到文件中,还可以通过电子邮件发送已识别的文本,只要输出格式受FineReader支持. ...

  2. python_Memcached

    一.Memcached 1.Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网 ...

  3. python_day7【模块configparser、XML、requests、shutil、系统命令-面向对象】之篇

    python内置模块补充 一.configparser configparser:用户处理特定格式的文件,其本质是利用open打开文件 # 节点 [section1] #键值对k1 = v1 k2:v ...

  4. 【转】ASP.NET Cookies简单应用 记住用户名和密码

    不要试图给Password类型的TextBox赋值! 在asp.net中,不要试图给Password类型的TextBox控件赋值! 无论是在设计或是运行时,都不可以的. 猜测的原因是,password ...

  5. OpenJudge计算概论-计算三角形面积【海伦公式】

    /*============================================== 计算三角形面积 总时间限制: 1000ms 内存限制: 65536kB 描述 平面上有一个三角形,它的 ...

  6. 【转】php curl 伪造IP来源的实例代码

    curl发出请求的文件fake_ip.php: 代码 复制代码 代码如下: <?php $ch = curl_init(); $url = "http://localhost/targ ...

  7. 解决Win10默认占用80端口

    方案1: 以管理员身份运行cmd;输入net stop http;如果提示是否真的需要停止这些服务,则选择“Y”;完成后输入:sc config http start=disabled 方案2: Ct ...

  8. R(二): http与R脚本通讯环境安装

    结合实际的工作环境,在开始R研究的时候,首先着手收集的就是能以Web方式发布R运行结果的基础框架,无耐的是,R一直以来常使用于个人电脑的客户端程序上,大家习惯性的下载R安装包,在自己的电脑上安装 -- ...

  9. java单例模式和双例模式

    今天朋友找我给做道题,双例模式,我是没听说过,都说是单例模式和多例模式, 也不知道双例模式什么时候用,就简单写了一个案例,不知道对不对,个人感觉蛮对的,双例就是单例+单例,废话不说了!!!! /* * ...

  10. 如何在ExtJS 6中使用Fashion美化应用程序

    在Ext JS 6,一个最大的改变就是框架合并,使用一个单一的代码库,就可以为每一种设备开发各具有良好体验的最好应用程序.它还带来了一种美化应用程序的新方式. 在本文,重点是Sencha Fashio ...