package com.itheima.trans;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; import com.itheima.util.DBUtil; public class TransDemo { /*
创建mysql数据库相关sql语句:
create database day11;
use day11;
create table account(
id int primary key auto_increment,
name varchar(20),
salary double
);
insert into account values(null, 'a', 1000);
insert into account values(null, 'b', 1000);
*/
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = DBUtil.getConn();
conn.setAutoCommit(false);//设置自己主动事务提交为false
//a给b转账-----a账户减去100块钱;b账户添加100块钱
ps = conn.prepareStatement("update account set salary=salary-100 where name=?");
ps.setString(1, "a");
ps.executeUpdate(); int i = 1 / 0; //设置异常 ps = conn.prepareStatement("update account set salary=salary+100 where name=? ");
ps.setString(1, "b");
ps.executeUpdate(); conn.commit();
} catch (Exception e) {
e.printStackTrace();
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
DBUtil.close(conn, ps, rs);
}
}
}

代码解析:

默认情况下每运行一条sql语句。就是运行一次事务,也就是每一条sql语句的运行都会是一次事务的提交。

在这个样例中假设a给b转账,a账户减去100的sql语句运行成功,这时伴随着一次的事务提交。数据库中的a账户金额减去100。而再运行b的账务添加100sql语句之前。出现了异常,这里我设了一个除以零异常,此时程序终止。bsql语句不再运行。

a账户扣了100,而b账户则金额不变。这时数据出错。

解决方法是:通过conn.setAutoCommit(false);方法设置事务自己主动提交为false。这时每一次的sql语句运行完毕后就不会提交事务,数据库中的数据并不会发生改变,当俩个sql都运行完毕,然后调用coon.commit();方法提交事务,此时数据库中的数据才会真正的改变。假设中途发生异常。通过conn.rollback();方法回滚,此时之前运行的sql语句的结果并不会提交。这样数据就不会出错了。

设置Savepoint:

package com.itheima.trans;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Savepoint; import com.itheima.util.DBUtil; public class TransDemo { /*
创建mysql数据库相关sql语句:
create database day11;
use day11;
create table account(
id int primary key auto_increment,
name varchar(20),
salary double
);
insert into account values(null, 'a', 1000);
insert into account values(null, 'b', 1000);
*/
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
Savepoint point = null;
try {
conn = DBUtil.getConn();
conn.setAutoCommit(false);//设置自己主动事务提交为false //a给b转账-----a账户减去100块钱。b账户添加100块钱
ps = conn.prepareStatement("update account set salary=salary-100 where name=?");
ps.setString(1, "a");
ps.executeUpdate(); ps = conn.prepareStatement("update account set salary=salary+100 where name=?");
ps.setString(1, "b");
ps.executeUpdate(); point = conn.setSavepoint();
int i = 1 / 0; //a给b转账-----a账户减去100块钱;b账户添加100块钱
ps = conn.prepareStatement("update account set salary=salary-100 where name=? ");
ps.setString(1, "a");
ps.executeUpdate(); ps = conn.prepareStatement("update account set salary=salary+100 where name=? ");
ps.setString(1, "b");
ps.executeUpdate(); conn.commit();
} catch (Exception e) {
e.printStackTrace();
try {
if(point == null) {
conn.rollback();
} else {
conn.rollback(point);
conn.commit();
}
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
DBUtil.close(conn, ps, rs);
}
}
}

版权声明:本文博主原创文章。博客,未经同意不得转载。

左右mysql事务提交的更多相关文章

  1. MySQL事务提交过程(二)

    上一篇文章我们介绍了在关闭binlog的情况下,事务提交的大概流程.之所以关闭binlog,是因为开启binlog后事务提交流程会变成两阶段提交,这里的两阶段提交并不涉及分布式事务,当然mysql把它 ...

  2. MySQL事务提交过程

    一.MySQL事务提交过程(一) MySQL作为一种关系型数据库,已被广泛应用到互联网中的诸多项目中.今天我们来讨论下事务的提交过程. 由于mysql插件式存储架构,导致开启binlog后,事务提交实 ...

  3. MySQL 事务提交 --不良好的事务习惯。

    MySQL 事务提交 --不良好的事务习惯 我们知道"事务"是数据库区别于文件系统的重要特性之一.MySQL的InnoDB引擎中的事务也完全符合ACID(原子性 一致性 隔离性 持 ...

  4. mysql 事务提交过程

     打开binlog选项后,执行事务提交命令时,就会进入两阶段提交模式.两阶段提交分为prepare阶段和commit两个阶段.流程如下 :这里面涉及到两个重要的参数:innodb_flush_log_ ...

  5. MySQL事务提交过程(一)

    MySQL作为一种关系型数据库,已被广泛应用到互联网中的诸多项目中.今天我们来讨论下事务的提交过程. MySQL体系结构 由于mysql插件式存储架构,导致开启binlog后,事务提交实质是二阶段提交 ...

  6. MySQL事务提交过程(转载)

    http://blog.csdn.net/sofia1217/article/details/53968214 上一篇文章我们介绍了在关闭binlog的情况下,事务提交的大概流程.之所以关闭binlo ...

  7. 对mysql事务提交、回滚的错误理解

    一.起因 begin或者START TRANSACTION开始一个事务 rollback事务回滚 commit 事务确认 人们对事务的解释如下:事务由作为一个单独单元的一个或多个SQL语句组成,如果其 ...

  8. mysql事务提交和回滚机制

    应用场景:   银行取钱,从ATM机取钱,分为以下几个步骤       1 登陆ATM机,输入密码:    2 连接数据库,验证密码:    3 验证成功,获得用户信息,比如存款余额等:    4 用 ...

  9. MySQL事务提交流程详解

    MySQL事务的提交采用两阶段提交协议, 前些日子和同事聊的时候发现对提交的细节还是有些模糊,这里对照MySQL源码详细记录一下,版本是MySQL5.7.36. 一. 事务的提交流程. 1. 获取 M ...

随机推荐

  1. JSP的学习(1)——基本知识与底层原理

    通过之前的学习,我们已经对Servlet有所了解,现在我们先来学习JSP,当能使用JSP进行友好的页面显示之后,再回去学习Servlet的其他高级特性会将整个学习很好的融入进来. JSP,即Java ...

  2. zipkin分布式链路追踪系统

    基于zipkin分布式链路追踪系统预研第一篇   分布式服务追踪系统起源于Google的论文“Dapper, a Large-Scale Distributed Systems Tracing Inf ...

  3. LLBL Gen Pro 5.0

    LLBL Gen Pro 5.0 企业应用开发入门 Solutions Design 公司于2016年5月发布了LLBL Gen Pro 5.0,这个新版本的发布出乎于我的意料.我的猜想是从4.2升级 ...

  4. Hadoop大数据零基础高端实战培训系列配文本挖掘项目

  5. JavaScript快速入门(六)——DOM

    概念扫盲 DOM DOM是 Document Object Model(文档对象模型)的缩写,是W3C(万维网联盟)的标准.DOM 定义了访问 HTML 和 XML 文档的标准:“W3C 文档对象模型 ...

  6. unity3d ngui-TweenRotation-TweenPosition-TweenScale

    using UnityEngine; using System.Collections; public class TweenFlipCARDS : MonoBehaviour { private f ...

  7. iOS国际化时遇到的错误:read failed: the data couldn't be read because it isn't in the correct format.

    事实上这个错误非常easy,就是当我们在国际化的时候,写key,写着写着就忘了加 ";" 所以查看一下自己的Localization文件就能够了

  8. TCP/IP协议全解析

    TCP/IP 是用于因特网 (Internet) 的通信协议. TCP/IP 是供已连接因特网的计算机进行通信的通信协议. TCP/IP 指传输控制协议/网际协议(Transmission Contr ...

  9. TMsgThread, TCommThread -- 在delphi线程中实现消息循环(105篇博客,好多研究消息的文章)

    在delphi线程中实现消息循环 在delphi线程中实现消息循环 Delphi的TThread类使用很方便,但是有时候我们需要在线程类中使用消息循环,delphi没有提供.   花了两天的事件研究了 ...

  10. Eclipse代码字体、颜色美化,更改字体大小、颜色

    先看效果: 感觉如何,是否比你的eclipse编辑器显示的代码要漂亮简洁呢?呵呵.这个是我原来ADT Eclipse的效果,现在去下居然更新掉了,找不到了.于是我就参照我原来的配置对这个新的Eclip ...