四大特性(ACID)
- 原子性(Atomicity):事务中所有操作是不可再分割的原子单位。事务中所有操作要么全部执行成功,要么全部执行失败。
- 一致性(Consistency):事务执行后,数据库状态与其它业务规则保持一致。如转账业务,无论事务执行与否,参与转账的两个账号余额之和应该是不变的。
- 隔离性(lsolation):隔离性是指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事物不会相互干扰。
- 持久性(Durability):一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证通过某种机制恢复数据。
Mysql中的事务
在默认情况下,Mysql每执行一条SQL语句,都是一个单独的事务。如果需要在一个事务中包含多条SQL语句,那么需要开启事务和结束事务。
- 开启事物:
start transaction
- 结束事务:
commit或rollback
在执行SQL语句之前,先执行start transaction
,这就开启了一个事务(事务的起点),然后可以去执行多条SQL语句,最后要结束事务,commit表示提交,即事务中的多条SQL语句所做出的影响会持久到数据库中。或者rollback表示回滚,即回滚到事务的起点,之前做的所有操作都被撤销了。
JDBC中操作事务
在JDBC中处理事务,都是通过Connection完成的。
同一事务中所有的操作,都在使用同一个Connection对象。
Connection的三个方法与事务相关
setAutoCommit(boolean):设置是否为自动提交事务,如果true(默认值就是true)表示自动提交,也就是每条执行的SQL语句都是一个单独的事务,如果设置false,那么就相当于开启了事务了;con.setAutoCommit(false)表示开启事务。
commit():提交结束事务;con.commit():表示事务。
- rollback():回滚结束事务;con.rollback():表示回滚事务。
//JDBC处理事务的代码格式
try{
con.setAutoCommit(false);//开启事务
...
con.commit();//try中最后提交事务。
}catch(exception e){
con.rollback();//回滚事务。
}
事务的隔离级别
并发事务导致问题大致有5类:其中两类是更新问题,三类是读问题。
并发事务的读问题
1.脏读(dirty read):读到另一个事务的未提交更新数据,即读取到了脏数据。
2.不可重复读(unrepeatable read):对同一记录的两次读取不一致,因为另一事务对该记录做了修改。
3.幻读(phantom read):对同一张表的两次查询不一致,因为另一事务插入一条记录。
不可重复读和幻读的区别
- 不可重复读是读取到了另一事务的更新。
- 幻读是读取到了另一事务的插入(Mysql中无法测试到幻读)。
四大隔离级别
4个等级的事务隔离级别,在相同数据环境下,使用相同的输入,执行相同的工作,根据不同的隔离级别,可以导致不同的结果,不同事务隔离级别能够解决的数据并发问题的能力是不同的。
- SERIALIZABLE(串行化)
- 不会出现任何并发问题,因为它是对同一数据的访问是串行的,非并发访问的;
- 性能最差;
- REPEATABLE(可重复读)(Mysql)
- 防止脏读和不可重复读,不能处理幻读问题;
- 性能比SERIALIZABLE好;
- READ COMMITTED(读已提交数据)(Oracle)
- 防止脏读,没有处理不可重复读,也没有处理幻读;
- 性能比REPEATABLE READ好;
- READ UNCOMMITTED(读未提交数据)
- 可能出现任何事物并发问题;
- 性能最好;
Mysql的默认隔离级别为REPEATABLE READ,这是一个很不错的选择。
Mysql中查看隔离级别:select @@tx_isolation
,设置隔离级别:set transaction isolationlevel 4选 1
jdbc设置隔离级别:con.setTransactionisolation(int level)
事务总结
- 事务的特性:ACID
- 事务开始边界与结束边界:开始边界(con.setAutoCommit(false)),结束边界(con.commit()或con.rollback());
- 事务的隔离级别:READ_UNCOMMITED,READ_COMMITED,REPEATABLE_READ,SERIALIZABLE.多个事务并发执行时才需要考虑并发事务。