—高级软件人才实作培训专家!
总结
今日内容
事务
连接池
ThreadLocal
BaseServlet 自定义 Servlet 父类(只要求会用,不要求会写)
DBUls commons-dbuls
事务
事务的四大特性:ACID;
mysql 中操作事务
jdbc 中操作事务
事务概述
为了方便演示事务,我们需要创建一个 account 表:
!"#
$%&"'(#
#)
*$%&#*+,-+"""""#)
北京传智播客教育 www.itcast.cn
—高级软件人才实作培训专家!
*$%&#*+%-+"""""#)
*$%&#*+..+"""""#)
*/0)
1 什么是事务
银行转账!张三转 10000 块到李四的账户,这其实需要两条 SQL 语句:
给张三的账户减去 10000 元;
给李四的账户加上 10000 元。
如果在第一条 SQL 语句执行成功后,在执行第二条 SQL 语句之前,程序被中断了(可能是抛出
了某个异常,也可能是其他什么原因),那么李四的账户没有加上 10000 元,而张三却减去了
10000 元。这肯定是不行的!
你现在可能已经知道什么是事务了吧!事务中的多个操作,要么完全成功,要么完全失败!不
可能存在成功一半的情况!也就是说给张三的账户减去 10000 元如果成功了,那么给李四的账户加
上 10000 元的操作也必须是成功的;否则给张三减去 10000 元,以及给李四加上 10000 元都是失败
的!
2 事务的四大特性(ACID)
面试!
事务的四大特性是:
原子性(Atomicity):事务中所有操作是不可再分割的原子单位。事务中所有操作要么全
部执行成功,要么全部执行失败。
一致性(Consistency):事务执行后,数据库状态与其它业务规则保持一致。如转账业务 ,
无论事务执行成功与否,参与转账的两个账号余额之和应该是不变的。
隔离性(Isolaon):隔离性是指在并发操作中,不同事务之间应该隔离开来,使每个并发
中的事务不会相互干扰。
持久性(Durability):一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据
库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证通过某种机制
恢复数据。
3 MySQL 中的事务
在默认情况下,MySQL 每执行一条 SQL 语句,都是一个单独的事务。如果需要在一个事务中包
含多条 SQL 语句,那么需要开启事务和结束事务。
开启事务:-11-2;
结束事务:33 或 1%%$4。
在执行 SQL 语句之前,先执行 strat transacon,这就开启了一个事务(事务的起点),然后可
以去执行多条 SQL 语句,最后要结束事务,commit 表示提交,即事务中的多条 SQL 语句所做出的
影响会持久化到数据库中。或者 rollback,表示回滚,即回滚到事务的起点,之前做的所有操作都
被撤消了!
北京传智播客教育 www.itcast.cn
—高级软件人才实作培训专家!
下面演示 zs 给 li 转账 10000 元的示例:
START TRANSACTION;
UPDATE account SET balance=balance-10000 WHERE id=1;
UPDATE account SET balance=balance+10000 WHERE id=2;
ROLLBACK;
START TRANSACTION;
UPDATE account SET balance=balance-10000 WHERE id=1;
UPDATE account SET balance=balance+10000 WHERE id=2;
COMMIT;
START TRANSACTION;
UPDATE account SET balance=balance-10000 WHERE id=1;
UPDATE account SET balance=balance+10000 WHERE id=2;
quit;
JDBC 事务
在 jdbc 中处理事务,都是通过 Connecon 完成的!
同一事务中所有的操作,都在使用同一个 &2 对象!
1 JDBC 中的事务
Connecon 的三个方法与事务相关:
setAutoCommit(boolean):设置是否为自动提交事务,如果 true(默认值就是 true)表示自
动提交,也就是每条执行的 SQL 语句都是一个单独的事务,如果设置 false,那么就相当于
开启了事务了;'-&335%-&#表示开启事务!!!
commit():提交结束事务;'33#)表示提交事务
rollback():回滚结束事务。'1%%$4#)表示回滚事务
jdbc 处理事务的代码格式:
try {
con.setAutoCommit(false);//开启事务…
….
…
con.commit();//try 的最后提交事务
} catch() {
con.rollback();//回滚事务
北京传智播客教育 www.itcast.cn
—高级软件人才实作培训专家!
}
public void transfer(boolean b) {
Connection con = null;
PreparedStatement pstmt = null;
try {
con = JdbcUtils.getConnection();
//手动提交
con.setAutoCommit(false);
String sql = "update account set balance=balance+? where id=?";
pstmt = con.prepareStatement(sql);
//操作
pstmt.setDouble(1, -10000);
pstmt.setInt(2, 1);
pstmt.executeUpdate();
// 在两个操作中抛出异常
if(b) {
throw new Exception();
}
pstmt.setDouble(1, 10000);
pstmt.setInt(2, 2);
pstmt.executeUpdate();
//提交事务
con.commit();
} catch(Exception e) {
//回滚事务
if(con != null) {
try {
con.rollback();
} catch(SQLException ex) {}
}
throw new RuntimeException(e);
} finally {
//关闭
JdbcUtils.close(con, pstmt);
北京传智播客教育 www.itcast.cn
—高级软件人才实作培训专家!
}
}
2 保存点(了解)
保存点是 JDBC3.0 的东西!当要求数据库服务器支持保存点方式的回滚。
校验数据库服务器是否支持保存点!
boolean b = con.getMetaData().supportsSavepoints();
保存点的作用是允许事务回滚到指定的保存点位置。在事务中设置好保存点,然后回滚时可以
选择回滚到指定的保存点,而不是回滚整个事务!注意,回滚到指定保存点并没有结束事务!!!
只有回滚了整个事务才算是结束事务了!
Connecon 类的设置保存点,以及回滚到指定保存点方法:
设置保存点:Savepoint setSavepoint();
回滚到指定保存点:void rollback(Savepoint)。
/*
* 李四对张三说,如果你给我转1W,我就给你转100W。
* ==========================================
*
* 张三给李四转1W(张三减去1W,李四加上1W)
* 设置保存点!
* 李四给张三转100W(李四减去100W,张三加上100W)
* 查看李四余额为负数,那么回滚到保存点。
* 提交事务
*/
@Test
public 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");
北京传智播客教育 www.itcast.cn