事务的四大特性
原子性(Atomicity):事务中所有操作是不可再分割的原子单位。事务中所有操作要么全部执行成功,要么全部执行失败。
一致性(Consistency):事务执行后,数据库状态与其他业务规则保持一致。
隔离性(Isolation):隔离性是指在并发操作中,不同事物之间应该隔离,使每个并发中的事务不会相互干扰。
持久性(Durability):一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证通过某种机制恢复数据。
MySQL中的事务
开启事务:start transaction
结束事务:commit或rollback
JDBC事务
同一事务中所有的操作都在使用同一个Connection
使用Connection三个与事务相关的方法:
>setAutoCommit(boolean):设置是否为自动提交事务。设置为false时表示事务开启
>commit()
>rollback()
代码格式:前两个方法放在try代码块中,rollback放在catch代码块中
public class AccountDao {
/*
* 修改指定用户的金额
* */
public void updateBalance(Connection con,String name,double balance){
try{
//给出SQL模板
String sql = "UPDATE account SET balance=balance+? WHERE username=?";
PreparedStatement ps = con.prepareStatement(sql);
//设置?
ps.setDouble(1, balance);
ps.setString(2, name);
//执行
ps.executeUpdate();
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
public class Demo1 {
public void zhuanzhang(String from,String to,Double money){
Connection con = null;
try{
con = JdbcUtils.getConnection();
//开启事务
con.setAutoCommit(false);
AccountDao dao = new AccountDao();
dao.updateBalance(con,from, -money);
dao.updateBalance(con,to, +money);
//提交事务
con.commit();
}catch(Exception e){
//回滚事务
try {
con.rollback();
con.close();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
@Test
public void fun1(){
zhuanzhang("冯绍峰","赵丽颖",3000.0);
}
}
事务隔离级别:
1.并发事务问题
因并发事务导致的问题有五类,其中两类是更新问题,三类为读问题。
脏读:又称无效数据读出。一个事务读取另外一个事务还没有提交的数据叫脏读。
例如:事务T1修改了一行数据,但是还没有提交,这时候事务T2读取了被事务T1修改后的数据,之后事务T1因为某种原因Rollback了,那么事务T2读取的数据就是脏的。
不可重复读:在一个事务内两次读到的数据不一样(通俗地讲,就是使用想相同的的条件进行查询 , 第一个事务读取过的数据 , 再次读取出来发现值不一样了,原因就是在两次查询的区间内,有另外一个事务将该数据更改了)
幻读(虚读):对同一张表的两次查询不一致,因为另一事务插入了一条记录;
不可重复读的重点是修改:相同的查询条件,第一次读取的数据,再次读取出来结果不一致;
幻读的重点在于新增或者删除: 相同的查询条件,第 1 次和第 2 次读出来的记录数不一样;
2.四大隔离级别
(1)SERIALIZABLE(串行化)
>不会出现任何并发问题,因为它是对同一数据的访问时穿行的,非并发访问
>执行效率低
>三种问题都能处理
(2)REPATABLEREAD(可重复读)
>防止脏读和不可重复读
>性能比SERIALIZABLE好
(3)READ COMMITTED(读已提交数据)
>防止脏读,没有处理不可重复读和幻读
>性能比REPATABLEREAD好
(4)READ UNCOMMITTED(读未提交数据)
>可能出现任何事物并发问题
>性能最好