Spring事务总结

我之前对事务一支半解,通过查资料,把一些模糊的知识弄懂了,感谢以下链接作者:

http://cupoy.javaeye.com/blog/251796

http://en.wikipedia.org/wiki/Isolation_%28computer_science%29#READ_COMMITTED (仔细阅读时发现与我参考的中文描述有出入, 可能是我的英文理解能力不够吧)

http://www.javaeye.com/topic/332577

http://www.javaeye.com/topic/866364

http://www.javaeye.com/topic/78674(介绍spring传播行为很详细)

几个重要概念:

1. 脏读 :脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。

{

A dirty read occurs when a transaction is allowed to read data from a row that has been modified by another running transaction not yet committed.

}

 

2. 不可重复读 :是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两 次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不 可重复读。例如,一个编辑人员两次读取同一文档,但在两次读取之间,作者重写了该文档。当编辑人员第二次读取文档时,文档已更改。原始读取不可重复。如果 只有在作者全部完成编写后编辑人员才可以读取文档,则可以避免该问题。

3. 幻读 : 是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。 同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象 发生了幻觉一样。例如,一个编辑人员更改作者提交的文档,但当生产部门将其更改内容合并到该文档的主复本时,发现作者已将未编辑的新材料添加到该文档中。 如果在编辑人员和生产部门完成对原始文档的处理之前,任何人都不能将新材料添加到文档中,则可以避免该问题。

{

A phantom read occurs when, in the course of a transaction, two identical queries are executed, and the collection of rows returned by the second query is different from the first. This can occur when range locks are not acquired on performing a SELECT ... WHERE operation. Phantom reads anomaly is an special case of Non-repeatable reads when Transaction 1 repeats a ranged SELECT ... WHERE query and, in the middle of both operations, Transaction 2 creates (i.e. INSERT ) new rows (in the target table) fulfilling that WHERE clause.

}

 

 

 

Spring 声明性事务的隔离(Isolation) 属性一共支持五种事务设置,具体介绍如下:

DEFAULT 使用数据库设置的隔离级别 ( 默认 ) ,由 DBA 默认的设置来决定隔离级别 .

READ_UNCOMMITTED 会出现脏读、不可重复读、幻读 ( 隔离级别最低,并发性能高 )

{

This is the lower isolation level. In this isolation level, dirty reads are allowed, so one transaction may see not-yet-committed changes made by some other transaction(s).

}

READ_COMMITTED   会出现不可重复读、幻读问题(锁定正在读取的行)

------所以T1第一次读完ID为1的记录后就放开锁了,所以T2此时可以对ID为1的记录进行修改并提交。当T1回头再读ID为1的记录时,数据已经跟第一次读的不一样了。

{

In this isolation level, a lock-based concurrency control DBMS implementation keeps write locks (acquired on selected data) till the end of the transaction (如果要等到整个T1结束后才开放所涉及的数据的写锁,那怎么会出现T2在T1结束事务前修改数据的情况呢?) , but read locks are released as soon as the SELECT operations is performed (so non-repeatable reads phenomenum can occur in this isolation level -see below-). As in the previous level, range-locks are not managed.

}

REPEATABLE_READ 会出幻读(锁定所读取的所有行)

------所以T1第一次读它范围以内的所有记录前,读锁跟写锁已经把这些记录给锁住了,T2无法修改。当T1完成了并放开这些行的锁后,T2才能够修改其中的行。所以这样就避免了“不可重复读”的情况出现。

{

In this isolation level, a lock-based concurrency control DBMS implementation keeps read and write locks (acquired on selected data) till the end of the transaction, but range-locks are not managed.

}

SERIALIZABLE 保证所有的情况不会发生

This is the higher isolation level. It specifies that all transactions occur in a completely isolated fashion; i.e. , as if all transactions in the system had executed serially, one after the other.

With a lock-based concurrency control DBMS implementation, serializability requires read and write locks (acquired on selected data) to be released at the end of the transaction. Also range-locks must be acquired when a SELECT query uses a ranged WHERE clause

 

 

spring的事务传播行为:
PROPAGATION_MANDATORY:该方法必须运行在一个事务中。如果当前事务不存在则抛出异常。
PROPAGATION_NESTED:外层事务的回滚可以引起内层事务的回滚。而内层事务的异常并不会导致外层事务的回滚,它是一个真正的嵌套事务。
PROPAGATION_NEVER:当前方法不应该运行在一个事务中。如果当前存在一个事务,则抛出异常。
PROPAGATION_NOT_SUPPORTED:当前方法不应该运行在一个事务中。如果一个事务正在运行,它将在该方法的运行期间挂起。
PROPAGATION_REQUIRED:该方法必须运行在一个事务中。如果一个事务正在运行,该方法将运行在这个事务中。否则,就开始一个新的事务。
PROPAGATION_REQUIRES_NEW:内层事务与外层事务就像两个独立的事务一样,一旦内层事务进行了提交后,外层事务不能对其进行回滚。两个事务互不影响。两个事务不是一个真正的嵌套事务。
PROPAGATION_SUPPORTS:当前方法不需要事务处理环境,但如果一个事务已经在运行的话,这个方法也可以在这个事务里运行。

 

猜你喜欢

转载自blog.csdn.net/yyb_gz/article/details/6193001