事务是指作为单个逻辑工作单元执行的一组相关操作。
这些操作要求全部完成或者全部不完成。
使用事务的原因:保证数据的安全有效。
事务控制使用:commit,savepoint,rollback;:
commit:提交事务,提交事务是指让这个事务里面的所有操作都生效到数据库中
rollback:回滚事务,回滚事务是指让这个事务里面的所有操作都撤销,rollback只能对
未提交的数据撤销,已经Commit的数据是无法撤销的,因为commit之后已经持久化到数据库中
当一个sql命令执行一个事务就开始了,当遇到以下情况,事务自动完成
1.commit或者rollback
2.DDL(修改表结构和约束)或者DCL命令执行
3.错误,退出,或者系统崩溃
事务的四个特点:(ACID)
1、原子性(Atomic):事务中所有数据的修改,要么全部执行,要么全部不执行。
只有所有的操作执行成功,整个事务才能提交,事务中任何一个数据库操作失败,己经执行的任何操作都必须撤销,让数据返回到初状态。
2、一致性(Consistence):事务完成时,要使所有所有的数据都保持一致的状态,换言之:通过事务进行的所有数据修改,必须在所有相关的表中得到反映。如从A账户转账100元到B账户,不管操作成功与否,A和B的存款总额不变的。
3、隔离性(Isolation):事务应该在另一个事务对数据的修改前或者修改后进行访问(事务之间互不影响)在并发数据操作时,不同的事务拥有各自的数据空间,它们的操作不会对对方产生干扰。准确地说,并非要求做到完全无干扰,数据库规定了多种事务隔离级别,不同隔离级别,对应不同的干扰程度,隔离级别越高,数据一致性越好,但并发性越弱。
4、持久性(Durability):保证事务对数据库的修改是持久有效的,一旦事务提交成功后,即使发生系统故障,也不应该丢失。
数据“一致性”是最终目标,其他特性都是为达到这个目标的措施、要求或手段。
数据并发的问题:
脏读(Dirty Read):A事务读取B事务尚未提交的更改数据,并在这个数据的基础上操作。如果恰巧B事务回滚,那么A事务读到的数据根本是不被承认的。事务T1更新了一行数据,还没有提交所做的修改,T2读取更新后的数据, T1回滚,T2读取的数据无效,这种数据称为脏读数据(如果读到了)。
不可重复读(UNrepeatable Read):A事务读取到了B事务已经提交的更改的数据。假设A在取款事务的过程中,B往该账户转账100元, A两次读取的账户的余额发生不一致事务T1读取一行数据,T2修改了T1刚刚读取的记录(并提交),T1再次查询,发现与第一次读取的记录不相同,称为不可重复读。
幻读(Phantom Read):A事务读取了B事务提交的新增数据,这时A事将出现幻象读.举一个例子,假设银行系统在同一个事务中,两次统计存款账户的总金额,在两次统计过程中刚好新增了一个存款户,并存入100元,这时两次统计的总金额不一致事务T1读取一条带WHERE条件的语句,返回结果集,T2插入一条新纪录,恰好也是T1的WHERE条件,T1再次查询,结果集中又看到T2的记录,新纪录就叫做幻读。
幻读和不可重复读是两个容易混淆的概念,前者是指读到了其他己经提交的事务的新增数据,而后者是指读到了己经提交事务的更改数据(更改或删除),为了避免这种情况,采取的对策是不同的一个着重对整张表,一个着重对某些记录加限制。
为了处理这些问题,SQL标准定义了以下几种事务隔离级别:
NO_TRANSACTION 不支持事务
READ UNCOMMITED 允许脏读、不可重复读、幻读
READ COMMITED 允许不可重复读、幻读,不允许脏读
REPEATABLE READ 允许幻读,不允许脏读、不可重复读
SERIALIZABLE 脏读、不可重复读、幻读都不允许
Oracle数据库支持READ COMMITTED(默认) 和 SERIALIZABLE这两种事务隔离级别(可以进行设置),所以Oracle始终不支持脏读。
时间 |
T1 |
T2 |
T3 |
t1 |
读A=50 |
|
|
A.不存在问题 B.将丢失修改 C.不能重复读 D.将读“脏”数据
隐式事务提交:
1.DDL语句(create..),执行commit
2.DCL语句(gant....),执行commit
3.正常退出终端。
note:如果系统崩溃,或者sqlplus不正常退出,事务回滚。
显示结束事务
commit:之前所做的所有会影响数据库的操作,都会对数据库产生持久的影响。
rollback:取消之前所做的所有操作
note:事务一旦提交,不能rollback
savepoint: 保存回滚点
savepoint point_name;
rollback to point_name;回滚到指定的标记点。标记点之后所做的所有操作都会被取消,但是之前的不受影响。
JDBC 事务
是用 Connection 对象控制的。JDBCConnection 接口( java.sql.Connection )提供了两种事务模式:自动提交和手工提交。 java.sql.Connection 提供了以下控制事务的方法:
public void setAutoCommit(boolean)
public boolean getAutoCommit()
public void commit()
public void rollback()