1、数据库范式
1)作用:
尽可能减少数据冗余
保证数据完整性
识别出实体、关系以及表的缺失
第一范式:字段都为单一属性,且属性为基础类型
第二范式:属性必须完全依赖关键字
第三范式:非主键属性不能依赖其他的非主键属性
2、事务的状态
1)事务的开始:
连接数据库,并执行第一条DML语句
前一个事务结束后,又输入了另外一条DML语句
2)事务的回滚:
roolback:回滚到插入前的状态
3)事务的结束:
执行一句DDL,DCL ,会自动commit
Exit:自动Commit
意外中止:断电-会rollback
执行commit:提交记录事务,结束。
4)savepoint保存点
任何地方都可以设置一个保存点,可以回滚到这个保存点
一、事务的处理:四要素:
1、原子性:事务在完成时,必须使所有的数据都保持一致状态,而且在相关数据中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。事务结束时,所有的内部数据结构都应该是正确的。
2、一致性:将事务中所做的操作捆绑成一个原子单元,即对于事务所进行的数据修改等操作,要么全部执行,要么全部不执行。
3、隔离性:由并发事务所做的修改必须与任何其他事务所做的修改相隔离。事务查看数据时数据所处的状态,要么是被另一并发事务修改之前的状态,要么是被另一并发事务修改之后的状态,即事务不会查看由另一个并发事务正在修改的数据。这种隔离方式也叫可串行性。
4、持久性意味着当系统或介质发生故障时,确保已提交事务的更新不能丢失。即一旦一个事务提交,DBMS保证它对数据库中数据的改变应该是永久性的,耐得住任何系统故障。持久性通过数据库备份和恢复来保证。
二、事务的处理:
1)事务的自动提交:JDBC连接的默认设置是自动提交(auto-commit mode)
当SQL语句结束时,会自动的调用连接的commit()方法
即每一条语句分别提交,或者说一个事务仅有一条语句
2)JDBC可以使自动提交模式失效
必须显式的使用commit()或者rollback()才能
通常rollback()是在遇到异常时才触发,即出现在catch子句中
开发人员可以灵活地将SQL语句组织为事务
3)事务的显示提交
JDBC处理的步骤:
用false作为参数调用setAutoCommit方法;
执行一或多个关于数据库的操作;
调用commit方法完成改变;
若出现异常,恢复上次提交后的改变,调用rollback方法;
用true作为参数调用setAutoCommit方法; 恢复自动提交事务开关。
通常在显示控制事务之后,又恢复原来的自动提交模式
三、事务的并发控制
脏读、不可重复读、幻读
(1)脏读:脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
例如:
张三的工资为5000,事务A中把他的工资改为8000,但事务A尚未提交。
与此同时,
事务B正在读取张三的工资,读取到张三的工资为8000。
随后,
事务A发生异常,而回滚了事务。张三的工资又回滚为5000。
最后,
事务B读取到的张三工资为8000的数据即为脏数据,事务B做了一次脏读。
(2)不可重复读:是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
例如:
在事务A中,读取到张三的工资为5000,操作没有完成,事务还没提交。
与此同时,
事务B把张三的工资改为8000,并提交了事务。
随后,
在事务A中,再次读取张三的工资,此时工资变为8000。在一个事务中前后两次读取的结果并不致,导致了不可重复读。
(3)幻读: 是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。
例如:
目前工资为5000的员工有10人,事务A读取所有工资为5000的人数为10人。
此时,
事务B插入一条工资也为5000的记录。
这是,事务A再次读取工资为5000的员工,记录为11人。此时产生了幻读。
不可重复读的重点是修改:
同样的条件,你读取过的数据,再次读取出来发现值不一样了
幻读的重点在于新增或者删除:
同样的条件,第 1 次和第 2 次读出来的记录数不一样
四、事务的隔离级别
1)
隔离级别 脏读 不可重复读 幻读
Read uncommited 是 是 是
Read Commited 否 是 是
Repeatable Read 否 否 是
Serilizable 否 否 否
2)事务的隔离度越高,数据访问的效率越低
提高事务的隔离度
需要额外的加锁和解锁的开销
导致数据库的并发程度降低
3)开发人员可利用Connection接口提供的方法显示的改变事务的隔离级别
setTransactionIsolation(int level)该设置仅对当前连接有效
int getTransactionIsolation()返回当前连接的隔离级别设置