废话不多说,直接开始正题。
首先从事务的原则说起:
· 原子性
表示组成一个事务的多个数据库操作是一个不可分隔的原子单元,只有所有的操作执行成功,整个事务才提交,事务中任何一个数据库操作失败,已经执行的任何操作都必须撤销,让数据库返回到初始状态;
· 一致性
事务操作成功后,数据库所处的状态和它的业务规则是一致的,即数据不会被破坏。如从A账户转账100元到B账户,不管操作成功与否,A和B的存款总额是不变的;
· 隔离性
在并发数据操作时,不同的事务拥有各自数据空间,它们的操作不会对对方产生干扰。准确的说,并非要求做到完全无干扰,数据库规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性越好,但并发性越弱;
· 持久性
一旦事务提交成功后,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证能够通过某种机制恢复数据。
数据库系统的责任和我们的wc中事务模块的任务:
在这些事务特性中,数据“一致性”是最终目标,其它的特性都是为达到这个目标的措施、要求或手段。数据库管理系统一般采用重执行日志保证原子性、一致性和持久性,重执行日志记录了数据库变化的每一个动作,数据库在一个事务中执行一部分操作后发生错误退出,数据库即可以根据重执行日志撤销已经执行的操作。此外,对于已经提交的事务,即使数据库崩溃,在重启数据库时也能够根据日志对尚未持久化的数据进行相应的重执行操作。因此,我们不必关心数据库事务的物理完整性,而应该关注在什么情况下使用数据库事务、事务对性能的影响,如何使用事务等等。
具体到我们的代码中应该是什么样呢?
首先看看在一个方法内的事务:
一般我们会这么写代码:
Connection conn=null; Statement stmt=null; try{ conn=JdbcUtils.getConnection(); conn.setAutoCommit(false); stmt=conn.createStatement(); stmt.execute("sql语句1"); stmt.execute("sql语句2"); conn.commit(); }catch(SQLException e){ try{ conn.rollback(); }catch(SQLException e){ e.printStackTrace(); } }finally{ JdbcUtils.close(conn,stmt); }