世界万事无简单一说, 每个事情基本上由多个小的事情来完成。有的事情会存在若小的事情不能同时完成的情况就取消所有的小的事情,直至都完成达到预期的效果才算完成!这样就用到了事务操作。在所有的sql语句完成之前,若发生异常,则让事务回滚到开始事务的时候,让事务结束;并且让已执行的sql语句作废。但是连接数据库的connnection与开启事务的connnection必须是一个。这样原来在dao层开启连接必须到service层一起执行了开启事务和处理异常。

一、事务:

一件事情有n个组成单元 :要不这n个组成单元同时成功, 要不n个单元就同时失败。就是将n个组成单元放到一个事务中!

二、mysql事务:

1、默认的事务:一条sql语句就是一个事务 。默认就开启事务并提交事务!

2、手动事务:

①、显示的开启一个事务:start transaction

此时进行的所有的修改都是内存里修改的,具体数据库内到底修改了没还是由是否提交来决定的!!!

当提交了就代表数据库修改了,当回滚了则没有修改!

但是需要注意的是无论数据库到底修改了没有,只要执行了SQL语句,在库内的表里的自增的序号会自动被占用了!!!

②、事务提交:commit

代表从开启事务到事务提交中间的所有的sql都认为有效! 真正的更新数据库!

③、事务的回滚:rollback

  代表事务的回滚--在其之前的所有的操作都作废了!回滚到start的地方,同时当前的事务结束了!

三、JDBC事务操作:

1、默认是自动事务:

执行sql语句:executeUpdate()  ---- 每执行一次executeUpdate方法 代表 事务自动提交(默认)<执行一句sql就是一个提交>

2、通过jdbc的API手动事务:

①、开启事务:conn.setAutoCommit(false);

此为设置为自动提交(改为false,也就是改为手动提交)

②、提交事务:conn.commit();

③、回滚事务:conn.rollback();          (都被封装成了方法)

注意:

控制事务的connnection必须是同一个!

执行sql的connection与开启事务的connnection必须是同一个才能对事务进行控制!!!

public static void main(String[] args) {
Connection conn = JDBCUtils.getConn();
Statement sta = null;
// Statement sta = conn.createStatement();
String sql = "insert into account(aname,money) values('wangwu',1000)";
// 手动开启事务
try {
sta = conn.createStatement();
conn.setAutoCommit(false);
sta.executeUpdate(sql);
} catch (SQLException e) {
// 回滚
try {
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} finally {//注意好位置
try {
// 提交事务
conn.commit();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}

注:

Statement 对象用于将 SQL 语句发送到数据库中。实际上有三种 Statement 对象,它们都作为在给定连接上执行 SQL 语句的包容器:Statement、PreparedStatement(它从 Statement 继承而来)和 CallableStatement(它从 PreparedStatement 继承而来)。它们都专用于发送特定类型的 SQL 语句: Statement 对象用于执行不带参数的简单 SQL 语句;PreparedStatement 对象用于执行带或不带 IN 参数的预编译 SQL 语句;CallableStatement 对象用于执行对数据库已存储过程的调用

Statement 接口提供了执行语句和获取结果的基本方法。PreparedStatement 接口添加了处理 IN 参数的方法;而 CallableStatement 添加了处理 OUT 参数的方法。

四、DBUtils事务操作:

QueryRunner:

1、有参构造:QueryRunner runner = new QueryRunner(DataSource dataSource);

有参构造将数据源(连接池)作为参数传入QueryRunner,QueryRunner会从连 接池中获得一个数据库连接资源操作数据库,所以直接使用无Connection参数   的update方法即可操作数据库

2、无参构造:QueryRunner runner = new QueryRunner();-

无参的构造没有将数据源(连接池)作为参数传入QueryRunner,那么我们在使  用QueryRunner对象操作数据库时要使用有Connection参数的方法

<因为有参无法保证connection的唯一性,所以需要无参构造---并且需要手动获取连接>

public class MyDBUtils {
public static final String DRIVER = "com.mysql.jdbc.Driver";
public static final String URL = "jdbc:mysql://localhost:3306/java0603?useUnicode=true&characterEncoding=UTF-8";
public static final String USERNAME = "root";
public static final String PASSWORD = "123456";
/*
* 创建连接池BasicDataSource
*/
public static BasicDataSource dataSource = new BasicDataSource();
//静态代码块(优先只执行一次)
static {
//对连接池对象 进行基本的配置
dataSource.setDriverClassName(DRIVER); // 这是要连接的数据库的驱动
dataSource.setUrl(URL); //指定要连接的数据库地址
dataSource.setUsername(USERNAME); //指定要连接数据的用户名
dataSource.setPassword(PASSWORD); //指定要连接数据的密码
}
/*
* 返回连接池对象
*/
public static DataSource getDataSource(){
return dataSource;
}
//返回一个连接对象
public static Connection getConn(){
Connection conn=null;
try {
conn= dataSource.getConnection();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
}
    public static void main(String[] args) {
//获取连接池对象
QueryRunner qr = new QueryRunner();
//获取连接对象
Connection conn = MyDBUtils.getConn();
String sql = "update account set money = money - ? where aname = ?";
try {
//开启事务
conn.setAutoCommit(false);
qr.update(conn,sql,100,"zhangsan");
} catch (SQLException e) {
//回滚事务
try {
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//提交事务
try {
conn.commit();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

五、转账实例:

public class AccountDao {
// 转出--需要和service层同一个conn 所以需要传值
public void Moneyout(
Connection conn,String out, double money) throws SQLException {
QueryRunner qr = new QueryRunner();
String sql = "update account set money = money - ? where aname = ?";
qr.update(conn, sql, money, out);
} // 转入
public void Moneyin(Connection conn,String in, double money) throws SQLException {
QueryRunner qr = new QueryRunner();
String sql = "update account set money = money + ? where aname = ?";
qr.update(conn, sql, money, in);
}
}
public class AccountService {
private AccountDao accountDao = new AccountDao();
// 转账--需要在此层处理事务,所以在此层获得CONN,再把这个参数传给dao层
public boolean transfer(String out, String in, double money) {
// 定义变量
boolean flag = true;
Connection conn = MyDBUtils.getConn();
try {
// 开启事务
conn.setAutoCommit(false);
accountDao.Moneyout(conn, out, money);
accountDao.Moneyin(conn, in, money);
} catch (SQLException e) {
flag = false;
// 如果出现异常,则flag返回一个false
// 回滚(当try出现异常后会执行catch,然后回滚到开启事务之前)
try {
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace(); } finally {
// 提交
try {
conn.commit();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return flag;
}
}
public class TransferServlet extends HttpServlet {
private AccountService accountService =new AccountService();
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取页面上值
//解决中文乱码
request.setCharacterEncoding("UTF-8");
//获取转出账户
String out = request.getParameter("out");
//获取转入账户
String in = request.getParameter("in");
//获取转账金额(从前台获取的都是String类型)
String moneyStr = request.getParameter("money");
//将字符串金额转成double
double money = Double.parseDouble(moneyStr);
//调用 Service层的转账方法
boolean flag = accountService.transfer(out, in, money);
//解决response乱码
response.setContentType("text/html;charset=utf-8");
if(flag){
response.getWriter().write("转账成功");
}else{
response.getWriter().write("转账失败");
} } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}

五、事务的特性和隔离级别:事务的特性ACID

    1、原子性(Atomicity)

    原子性是指事务是一个不可分割的工作单位,事务中的操作 要么都发生,要么都不发生。

     2、一致性(Consistency)

    一个事务中,事务前后数据的完整性必须保持一致。

     3、隔离性(Isolation)

    多个事务,事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。

     4、持久性(Durability)

    持久性是指一个事务一旦被提交,它对数据库中数据的改变 就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

JAVA基础之事务的更多相关文章

  1. [Java面经]干货整理, Java面试题(覆盖Java基础,Java高级,JavaEE,数据库,设计模式等)

    如若转载请注明出处: http://www.cnblogs.com/wang-meng/p/5898837.html   谢谢.上一篇发了一个找工作的面经, 找工作不宜, 希望这一篇的内容能够帮助到大 ...

  2. Java基础知识【上】(转载)

    http://blog.csdn.net/silentbalanceyh/article/details/4608272 (最终还是决定重新写一份Java基础相关的内容,原来因为在写这一个章节的时候没 ...

  3. Java基础常见英语词汇

    Java基础常见英语词汇(共70个) ['ɔbdʒekt] ['ɔ:rientid]导向的                             ['prəʊɡræmɪŋ]编程 OO: object ...

  4. JAVA基础英语单词表(下)

    quantity                     / 'kwɔntiti /                    量,数量 query                             ...

  5. Java中的事务——JDBC事务和JTA事务

    Java中的事务——JDBC事务和JTA事务 转载:http://www.hollischuang.com/archives/1658 之前的事务介绍基本都是数据库层面的事务,本文来介绍一下J2EE中 ...

  6. Java 基础知识总结

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.数据类型:  数据类型:1>.基本数据类型:1).数值型: 1}.整型类型(byte  8位   (by ...

  7. 学习Spring必学的Java基础知识(1)----反射(转)

    引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓"登高必自卑,涉远必自迩".以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系 ...

  8. 学习Spring必学的Java基础知识(1)----反射

    引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓"登高必自卑,涉远必自迩".以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系 ...

  9. Java基础学习(1)——反射

    反射就是把Java类中的各种成分映射成相应的Java类(主要用于框架开发) 反射的基石–>Class类 Java程序中的各个类属于同一事物,描述这类事务的Java类名就是Class. Class ...

随机推荐

  1. Java基础 awt Button 鼠标放在按钮上背景颜色改变,鼠标离开背景颜色恢复

        JDK :OpenJDK-11      OS :CentOS 7.6.1810      IDE :Eclipse 2019‑03 typesetting :Markdown   code ...

  2. Python3基础 from...import 局部导入

             Python : 3.7.3          OS : Ubuntu 18.04.2 LTS         IDE : pycharm-community-2019.1.3    ...

  3. MySQL 使用 ON UPDATE CURRENT_TIMESTAMP 自动更新 timestamp (转)

    原文地址: https://blog.csdn.net/heatdeath/article/details/79833492 `create_time` timestamp not null defa ...

  4. SAP翔子_增强篇索引

    序号 描述 SAP翔子_增强篇0 增强篇0 SAP的多种增强方式 SAP翔子_增强篇1 增强篇1 PO保存增强 SAP翔子_增强篇2 增强篇2 生产订单屏幕增强 SAP翔子_增强篇3 增强篇3 SAP ...

  5. java学习摘抄笔记mybaits1

    mybatis 第一天 mybatis的基础知识 课程安排: mybatis和springmvc通过订单商品 案例驱动 第一天:基础知识(重点,内容量多) 对原生态jdbc程序(单独使用jdbc开发) ...

  6. [K8s] Kubernetes 是什么 不是什么

    现在有三种部署方式,传统物理机部署.虚拟机部署.容器化部署. 我们现在所使用的云上服务器一般都是虚拟化出来的,硬件资源独立,操作系统等软件资源亦独立. 容器化的好处是更轻量,复用下层的操作系统,相当于 ...

  7. SpringBoot系列教程web篇之404、500异常页面配置

    接着前面几篇web处理请求的博文,本文将说明,当出现异常的场景下,如404请求url不存在,,403无权,500服务器异常时,我们可以如何处理 原文友链: SpringBoot系列教程web篇之404 ...

  8. static示例

    求生成对象的个数 class A{ private int i; private static int cnt = 0; //此处用static修饰,让cnt属于类,多个对象共用一个属性,减少内存分配 ...

  9. LeetCode 942. 增减字符串匹配(DI String Match) 49

    942. 增减字符串匹配 942. DI String Match 题目描述 每日一算法2019/6/21Day 49LeetCode942. DI String Match Java 实现 and ...

  10. [转帖]技术人眼中的Facebook Libra

    技术人眼中的Facebook Libra https://www.jianshu.com/p/ddc733077749 比特币 以太坊 EOS Libra 0.8352019.07.01 14:15: ...