日期:2014-05-16 浏览次数:20517 次
并发带来的问题
A.第一类丢失更新:a事务回滚覆盖了b事务提交的数据;
???? a事物改,b事物改,a事物回滚?,b事物的更新被覆盖
B.脏读:一个事务读到另一个事务未提交的更新数据。
C.不可重复读:开始事物》读一次一个数》该数被其他事物修改并提交》再读结果变了》关闭事物
D.第二类丢失更新::a事务覆盖了b事务提交的数据.
??? a事物读,b事物读,a事物改提交,b事物改提交,a事物的提交被覆盖
E.幻读:一个事务读到另一个事务已提交的新插入的数据。
数据库系统提供了四种事务隔离级别
●?? 读取未提交(Read Uncommitted):允许脏读取,但不允许更新丢失。如果一个事务已经开始写数据,则另外一个数据则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。
a事物改(未提交)就不让b事物改(b等着a提交或回滚才可以操作),所以a事物的回滚不会覆盖掉b提交的数据,所以读未提交可以避免第一类丢失更新。
●?? 读取已提交(Read Committed):允许不可重复读取,但不允许脏读取。这可以通过“瞬间共享读锁”和“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。
a事物改了并且提交,b事物才可以读到a事物的更新,所以它可以避免脏读
●?? 可重复读取(Repeatable Read):禁止不可重复读取和脏读取,但是有时可能出现幻影数据。这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
a开始读就不让其他事物改,可以避免a两次读取不一致
●?? 序列化(Serializable):提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。?
a事物开始(不管读或写)b事物都得等着,所以可以避免任何并发问题(包括幻读/第二类更新丢失)
隔离级别可以避免的并发问题
?
?
读未提交(Read uncommitted) | 可能 | 可能 | 可能 |
读已提交(Read committed) | 不可能 | 可能 | 可能 |
可重复读(Repeatable read) | 不可能 | 不可能 | 可能 |
可串行化(Serializable ) | 不可能 | 不可能 | 不可能 |
Spring框架提供五种隔离级别分别为
ISOLATION_DEFAULT
ISOLATION_READ_UNCOMMITTED
ISOLATION_READ_COMMITTED
ISOLATION_REPEATABLE_READ
ISOLATION_SERIALIZABLE
后四种隔离级别具体隔离何种数据读取这个默认隔离级别是与具体的数据库相关的采取的是具体数据库的默认隔离级别不同的数据库是不一样的
?
?
?常用数据库默认隔离级别
Oracle默认的是read committed
MySql是REPEATABLE-READ(INNODB)
SQL Server 默认级别read committed
?
Read Commited与锁
?
当数据库系统采用read Commited隔离级别时,会导致不可重复的第二类丢失更新的并发问题,可以在应用程序中采用悲观锁或乐观锁来避免这类问题。从应用程序的角度,锁可以分为以下几类:?
A.悲观锁:指在应用程序中显示的为数据资源加锁。尽管能防止丢失更新和不可重复读这类并发问题,但是它会影响并发性能,因此应该谨慎地使用。?