数据库事务总结
2015-08-12 01:28
309 查看
数据库并发访问会出现以下4种问题:
1、第一类丢失更新:事务B嵌套在事务A中,事务B已经更新,之后事务A更新失败,A回滚,丢失了B的更新。(支持事务的数据库不会出现此问题)
2、脏读:读到其他事务还未提交的数据。
3、不可重复读:在同一事务中,两次读取的数据不一致。(被其他事务修改了)
4、幻读:两次读取的记录数不一致。(针对插入和删除操作)
设置数据库的事务隔离级别可以防止以上问题:
数据库一般的默认隔离离级别是“读已提交”,默认的事务隔离级别下:Insert,update ,delete下的是X锁, 会等待事务完成。通常情况下可以把隔离级别设为Read Commited,它能避免脏读,而且有较好的并发性能。尽管它会导致不可重复读、虚读和第二类更新丢失等问题,在可能出现这类问题的个别场合可以由应用程序釆用悲观锁或乐观锁来控制。
MySQL的默认事务隔离级别是REPEATABLE_READ,ORACLE、SQL Server、DB2和PostgreSQL的默认事务隔离级别是READ_COMMITED。
1、第一类丢失更新:事务B嵌套在事务A中,事务B已经更新,之后事务A更新失败,A回滚,丢失了B的更新。(支持事务的数据库不会出现此问题)
2、脏读:读到其他事务还未提交的数据。
3、不可重复读:在同一事务中,两次读取的数据不一致。(被其他事务修改了)
4、幻读:两次读取的记录数不一致。(针对插入和删除操作)
设置数据库的事务隔离级别可以防止以上问题:
隔离级别 | 脏读(Dirty Read) | 不可重复读(NonRepeatable Read) | 幻读(Phantom Read) | 说明(MSSQL2000中测试) |
读未提交(Read uncommitted) | 可能 | 可能 | 可能 | |
读已提交(Read committed) | 不可能 | 可能 | 可能 | 1、保证查询到的是其他事务已经提交的数据。(Update/Delete/Insert语句优先) 2、测试语句如下,先执行事务A,再执行事务B: 事务A: begin tran SET TRAN ISOLATION LEVEL READ COMMITTED --update ql_车号 set 车号=车号 +'1' --insert into ql_车号 values('aaa33') delete from ql_车号 where 车号= 'aaa11' select * from ql_车号 waitfor delay '00:00:03' commit 事务B: begin tran SET TRAN ISOLATION LEVEL READ COMMITTED select * from ql_车号 --waitfor delay '00:00:03' --select * from ql_车号 --waitfor delay '00:00:04' commit |
可重复读(Repeatable read) | 不可能 | 不可能 | 可能 | 1、保证在同一事务中,前后读出的数据是一致的。(Select语句优先) 2、先事务A读取数据,事务A完毕前,执行事务B修改数据.事务B中使用Update或Delete语句,若有符合条件的数据,则等待事务A执行完成再执行事务B;若没有符合条件的数据(即不会影响原来的数据),则事务A、B各自执行。 3、对事务B中的Insert语句不起作用。(所以会出现幻读) 4、测试语句如下,先执行事务A,再执行事务B: 事务A: begin tran SET TRAN ISOLATION LEVEL REPEATABLE READ select * from ql_车号 waitfor delay '00:00:03' select * from ql_车号 commit 事务B: begin tran SET TRAN ISOLATION LEVEL REPEATABLE READ --update ql_车号 set 车号=车号 +'1' delete from ql_车号 where 车号= 'aaa' select * from ql_车号 commit |
可串行化(Serializable ) | 不可能 | 不可能 | 不可能 |
MySQL的默认事务隔离级别是REPEATABLE_READ,ORACLE、SQL Server、DB2和PostgreSQL的默认事务隔离级别是READ_COMMITED。
相关文章推荐
- xampp修改mysql的默认空密码
- 对sql的查询语句做成对象式,简单实现。Where部分
- ORACLE 11g RAC 之健忘与脑裂
- MySQL你让我情何以堪
- 为什么pyspider+mongodb只存了一部分数据到数据库,而其他大量数据并没有写入数据库!
- asp.net中oracle 存储过程(代码+图文)
- 一次MySQL慢查询导致的故障
- MySQL备份与恢复之冷备(1)
- MySQL备份与恢复之真实环境使用冷备(2)
- MySQL备份与恢复之热备(3)
- MySQL备份与恢复之热拷贝(4)
- 简单的MySQL备份与还原方法分享
- Web安全之SQL注入攻击
- Playframework - 如何解决两个JPA同时访问一个数据库但是不更新Model的id名字
- 数据库堵了?还是被堵了?
- mysql存储过程
- mybatis数据批量插入
- 让Gitlab的CE版本,使用mysql数据库
- 安卓sqlite之增删改查(一)
- MySQL运行状态show status中文详解