事务
来源:互联网 发布:注册淘宝卖家要钱吗 编辑:程序博客网 时间:2024/06/04 20:01
1、事务概述
事务(Transaction)是并发控制的基本单位。它是一个操作序列,这些操作要么都执行,要么都不执行,是一个不可分割的工作单位。事务具有四大特性,简称为ACID:
● 原子性(Atomicity):事务中所有操作是不可再分割的原子单位。事务中所有操作要么全部执行成功,要么全部执行失败。
● 一致性(Consistency):事务执行后,数据库状态与其它业务规则保持一致。如转账业务,无论事务执行成功与否,参与转账的两个账号余额之和应该是不变的。
● 隔离性(Isolation):隔离性是指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会相互干扰。
● 持久性(Durability):一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证通过某种机制恢复数据。
2、数据库中的事务
在默认情况下,数据库中每执行一条SQL语句,都是一个单独的事务。如果需要在一个事务中包含多条SQL语句,需要开启事务和结束事务:
开启事务:start transaction;
结束事务:commit或rollback。
在执行SQL语句之前,先执行strat transaction,这就开启了一个事务(事务的起点),然后可以去执行多条SQL语句,最后要结束事务,使用commit表示提交,即事务中的多条SQL语句所做出的影响会持久化到数据库中。或者rollback,表示回滚,即回滚到事务的起点,将之前代码所做的所有操作撤消,并结束事务。
数据库转账事务实例:
<pre name="code" class="sql"><span style="font-size:18px;">START TRANSACTION; /*开启事务UPDATE account SET balance=balance-10000 WHERE id=1; /*1号id余额减少10000UPDATE account SET balance=balance+10000 WHERE id=2; /*2号id余额增加一万COMMIT;/*提交事务</span>
3、JDBC中的事务
在JDBC中,Connection的三个方法与事务相关:
● setAutoCommit(boolean):设置是否为自动提交事务,如果true(默认值就是true)表示自动提交,也就是说默认每条执行的SQL语句都是一个单独的事务,都被放在一个事务中,并且被默认设置为自动提交。如果我们设置为false,那么就相当于开启了事务了,con.setAutoCommit(false)表示开启事务;
● commit():提交结束事务,con.commit();表示提交事务;
● rollback():回滚结束事务,con.rollback();表示回滚事务;
JDBC处理事务的代码格式:
<span style="font-size:18px;">try { con.setAutoCommit(false);//开启事务… …. … con.commit();//try的最后提交事务} catch() { con.rollback();//如果try中代码出错则回滚事务}</span>
3、JDBC保存点
保存点在JDBC3.0中出现,校验当前数据库服务器是否支持保存点的方法是:
<span style="font-size:18px;">boolean b = con.getMetaData().supportsSavepoints();</span>
保存点的作用是允许事务回滚到指定的保存点位置。在事务中设置好保存点,回滚时可以选择回滚到指定的保存点,而不是回滚整个事务。注意,回滚到指定保存点并没有结束事务,只有回滚了整个事务才算是结束事务了。回滚到保存点只是表明回滚到保存点处的操作状态,并不回滚代码,代码还要从开始回滚处向下执行。
Connection类的设置保存点,以及回滚到指定保存点方法:
设置保存点:Savepoint setSavepoint();
回滚到指定保存点:void rollback(Savepoint)。
转账实例:
<span style="font-size:18px;">/* * 张三给李四转1W,李四给张三转100W。 * 操作步骤: * 1、张三给李四转1W(张三减去1W,李四加上1W) * 2、设置保存点 * 3、李四给张三转100W(李四减去100W,张三加上100W) * 4、查看李四余额为负数,那么回滚到保存点。 * 5、提交事务 */@Testpublic void fun() {Connection con = null;PreparedStatement pstmt = null;try {con = JdbcUtils.getConnection();//手动提交con.setAutoCommit(false);String sql = "update account set balance=balance+? where name=?";pstmt = con.prepareStatement(sql);//操作1(张三减去1W)pstmt.setDouble(1, -10000);pstmt.setString(2, "zs");pstmt.executeUpdate();//操作2(李四加上1W)pstmt.setDouble(1, 10000);pstmt.setString(2, "ls");pstmt.executeUpdate();// 设置保存点Savepoint sp = con.setSavepoint();//操作3(李四减去100W)pstmt.setDouble(1, -1000000);pstmt.setString(2, "ls");pstmt.executeUpdate();//操作4(张三加上100W)pstmt.setDouble(1, 1000000);pstmt.setString(2, "zs");pstmt.executeUpdate();//操作5(查看李四余额)sql = "select balance from account where name=?";pstmt = con.prepareStatement(sql);pstmt.setString(1, "ls");ResultSet rs = pstmt.executeQuery();rs.next();double balance = rs.getDouble(1); //如果李四余额为负数,那么回滚到指定保存点if(balance < 0) {con.rollback(sp); //回滚到指定保存点System.out.println("余额不足,回滚事务。");}//提交事务con.commit();} catch(Exception e) {//回滚事务if(con != null) {try {con.rollback();} catch(SQLException ex) {}}throw new RuntimeException(e);} finally {//关闭JdbcUtils.close(con, pstmt);}}</span>
张三减少1万,李四增加1万后设置了sp保存点,如果接下来程序发现李四余额不足100万,那么就会回滚到sp,也就是说:张三没有得到任何回报就失去了1万。
小结:事务是一个并发控制的基本单位,是一个操作序列,其内的操作要么全部执行,要么都不执行。ACID是事务的基本特性。此外,事务回滚分全部回滚和回滚到保存点,只有全部回滚时才会结束事务,否则代码继续向下执行。
- 事务
- 事务
- 事务
- 事务
- 事务
- 事务
- 事务
- 事务
- 事务
- 事务
- 事务
- 事务
- 事务
- 事务
- 事务
- 事务
- 事务
- 事务
- SonarQube代码质量管理平台安装与使用
- android值得推荐的开源框架简介
- Log4j中DailyRollingFileAppender日志文件清理策略
- Javascript学习笔记01——JS简介
- 数值的整数次方
- 事务
- 多种方案解决*** Assertion failure in -[UIApplication _runWithMainScene:transitionContext:completion:]
- 前端设计必备-Font awesome 插件使用菜鸟言语
- drbd主从
- Spans
- picamera 1.10 教程及api中文简译(三)picamera的基本使用
- linux cron实战:定时github
- Git的使用
- form表单submit提交时,用ajax做异步验证