Spring事務配置的五種方式和spring里面事務的傳播屬性和事務隔離級別、不可重復讀與幻讀的區別

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。

spring事務配置的五種方式

?

前段時間對Spring的事務配置做了比較深入的研究,在此之間對Spring的事務配置雖說也配置過,但是一直沒有一個清楚的認識。通過這次的學習發覺Spring的事務配置只要把思路理清,還是比較好掌握的。

??? 總結如下:

??? Spring配置文件中關于事務配置總是由三個組成部分,分別是DataSource、TransactionManager和代理機制這三部分,無論哪種配置方式,一般變化的只是代理機制這部分。

??? DataSource、TransactionManager這兩部分只是會根據數據訪問方式有所變化,比如使用hibernate進行數據訪問時,DataSource實際為SessionFactory,TransactionManager的實現為HibernateTransactionManager。

? ?

?

??? 根據代理機制的不同,總結了五種Spring事務的配置方式,配置文件如下:

??? 第一種方式:每個Bean都有一個代理

<?xml version="1.0" encoding="UTF-8"?>
<beans?xmlns="http://www.springframework.org/schema/beans"
??? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
??? xmlns:context="http://www.springframework.org/schema/context"
??? xmlns:aop="http://www.springframework.org/schema/aop"
??? xsi:schemaLocation="http://www.springframework.org/schema/beans?
?????????? http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
?????????? http://www.springframework.org/schema/context
?????????? http://www.springframework.org/schema/context/spring-context-2.5.xsd
?????????? http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
>

????<bean?id="sessionFactory"??
??????????? class
="org.springframework.orm.hibernate3.LocalSessionFactoryBean">??
????????
<property?name="configLocation"?value="classpath:hibernate.cfg.xml"?/>??
????????
<property?name="configurationClass"?value="org.hibernate.cfg.AnnotationConfiguration"?/>
????</bean>??

????
<!--?定義事務管理器(聲明式的事務)?-->??
????
<bean?id="transactionManager"
??????? class="org.springframework.orm.hibernate3.HibernateTransactionManager">
????????<property?name="sessionFactory"?ref="sessionFactory"?/>
????</bean>
????
????
<!--?配置DAO?-->
????<bean?id="userDaoTarget"?class="com.bluesky.spring.dao.UserDaoImpl">
????????<property?name="sessionFactory"?ref="sessionFactory"?/>
????</bean>
????
????
<bean?id="userDao"??
??????? class
="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">??
???????????
<!--?配置事務管理器?-->??
???????????
<property?name="transactionManager"?ref="transactionManager"?/>?????
????????
<property?name="target"?ref="userDaoTarget"?/>??
?????????
<property?name="proxyInterfaces"?value="com.bluesky.spring.dao.GeneratorDao"?/>
????????<!--?配置事務屬性?-->??
????????
<property?name="transactionAttributes">??
????????????
<props>??
????????????????
<prop?key="*">PROPAGATION_REQUIRED</prop>
????????????</props>??
????????
</property>??
????
</bean>??
</beans>

??? 第二種方式:所有Bean共享一個代理基類

<?xml version="1.0" encoding="UTF-8"?>
<beans?xmlns="http://www.springframework.org/schema/beans"
??? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
??? xmlns:context="http://www.springframework.org/schema/context"
??? xmlns:aop="http://www.springframework.org/schema/aop"
??? xsi:schemaLocation="http://www.springframework.org/schema/beans?
?????????? http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
?????????? http://www.springframework.org/schema/context
?????????? http://www.springframework.org/schema/context/spring-context-2.5.xsd
?????????? http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
>

????<bean?id="sessionFactory"??
??????????? class
="org.springframework.orm.hibernate3.LocalSessionFactoryBean">??
????????
<property?name="configLocation"?value="classpath:hibernate.cfg.xml"?/>??
????????
<property?name="configurationClass"?value="org.hibernate.cfg.AnnotationConfiguration"?/>
????</bean>??

????
<!--?定義事務管理器(聲明式的事務)?-->??
????
<bean?id="transactionManager"
??????? class="org.springframework.orm.hibernate3.HibernateTransactionManager">
????????<property?name="sessionFactory"?ref="sessionFactory"?/>
????</bean>
????
????
<bean?id="transactionBase"??
??????????? class
="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"??
??????????? lazy-init
="true"?abstract="true">??
????????
<!--?配置事務管理器?-->??
????????
<property?name="transactionManager"?ref="transactionManager"?/>??
????????
<!--?配置事務屬性?-->??
????????
<property?name="transactionAttributes">??
????????????
<props>??
????????????????
<prop?key="*">PROPAGATION_REQUIRED</prop>??
????????????
</props>??
????????
</property>??
????
</bean>????
???
????
<!--?配置DAO?-->
????<bean?id="userDaoTarget"?class="com.bluesky.spring.dao.UserDaoImpl">
????????<property?name="sessionFactory"?ref="sessionFactory"?/>
????</bean>
????
????
<bean?id="userDao"?parent="transactionBase"?>??
????????
<property?name="target"?ref="userDaoTarget"?/>???
????
</bean>
</beans>

第三種方式:使用攔截器

<?xml version="1.0" encoding="UTF-8"?>
<beans?xmlns="http://www.springframework.org/schema/beans"
??? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
??? xmlns:context="http://www.springframework.org/schema/context"
??? xmlns:aop="http://www.springframework.org/schema/aop"
??? xsi:schemaLocation="http://www.springframework.org/schema/beans?
?????????? http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
?????????? http://www.springframework.org/schema/context
?????????? http://www.springframework.org/schema/context/spring-context-2.5.xsd
?????????? http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
>

????<bean?id="sessionFactory"??
??????????? class
="org.springframework.orm.hibernate3.LocalSessionFactoryBean">??
????????
<property?name="configLocation"?value="classpath:hibernate.cfg.xml"?/>??
????????
<property?name="configurationClass"?value="org.hibernate.cfg.AnnotationConfiguration"?/>
????</bean>??

????
<!--?定義事務管理器(聲明式的事務)?-->??
????
<bean?id="transactionManager"
??????? class="org.springframework.orm.hibernate3.HibernateTransactionManager">
????????<property?name="sessionFactory"?ref="sessionFactory"?/>
????</bean>?
???
????
<bean?id="transactionInterceptor"??
??????? class
="org.springframework.transaction.interceptor.TransactionInterceptor">??
????????
<property?name="transactionManager"?ref="transactionManager"?/>??
????????
<!--?配置事務屬性?-->??
????????
<property?name="transactionAttributes">??
????????????
<props>??
????????????????
<prop?key="*">PROPAGATION_REQUIRED</prop>??
????????????
</props>??
????????
</property>??
????
</bean>
??????
????
<bean?class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">??
????????
<property?name="beanNames">??
????????????
<list>??
????????????????
<value>*Dao</value>
????????????</list>??
????????
</property>??
????????
<property?name="interceptorNames">??
????????????
<list>??
????????????????
<value>transactionInterceptor</value>??
????????????
</list>??
????????
</property>??
????
</bean>??
??
????
<!--?配置DAO?-->
????<bean?id="userDao"?class="com.bluesky.spring.dao.UserDaoImpl">
????????<property?name="sessionFactory"?ref="sessionFactory"?/>
????</bean>
</beans>

第四種方式:使用tx標簽配置的攔截器

<?xml version="1.0" encoding="UTF-8"?>
<beans?xmlns="http://www.springframework.org/schema/beans"
??? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
??? xmlns:context="http://www.springframework.org/schema/context"
??? xmlns:aop="http://www.springframework.org/schema/aop"
??? xmlns:tx="http://www.springframework.org/schema/tx"
??? xsi:schemaLocation="http://www.springframework.org/schema/beans?
?????????? http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
?????????? http://www.springframework.org/schema/context
?????????? http://www.springframework.org/schema/context/spring-context-2.5.xsd
?????????? http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
?????????? http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
>

????<context:annotation-config?/>
????<context:component-scan?base-package="com.bluesky"?/>

????<bean?id="sessionFactory"??
??????????? class
="org.springframework.orm.hibernate3.LocalSessionFactoryBean">??
????????
<property?name="configLocation"?value="classpath:hibernate.cfg.xml"?/>??
????????
<property?name="configurationClass"?value="org.hibernate.cfg.AnnotationConfiguration"?/>
????</bean>??

????
<!--?定義事務管理器(聲明式的事務)?-->??
????
<bean?id="transactionManager"
??????? class="org.springframework.orm.hibernate3.HibernateTransactionManager">
????????<property?name="sessionFactory"?ref="sessionFactory"?/>
????</bean>

????<tx:advice?id="txAdvice"?transaction-manager="transactionManager">
????????<tx:attributes>
????????????<tx:method?name="*"?propagation="REQUIRED"?/>
????????</tx:attributes>
????</tx:advice>
????
????
<aop:config>
????????<aop:pointcut?id="interceptorPointCuts"
??????????? expression="execution(* com.bluesky.spring.dao.*.*(..))"?/>
????????<aop:advisor?advice-ref="txAdvice"
??????????? pointcut-ref="interceptorPointCuts"?/>????????
????
</aop:config>??????
</beans>

第五種方式:全注解

<?xml version="1.0" encoding="UTF-8"?>
<beans?xmlns="http://www.springframework.org/schema/beans"
??? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
??? xmlns:context="http://www.springframework.org/schema/context"
??? xmlns:aop="http://www.springframework.org/schema/aop"
??? xmlns:tx="http://www.springframework.org/schema/tx"
??? xsi:schemaLocation="http://www.springframework.org/schema/beans?
?????????? http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
?????????? http://www.springframework.org/schema/context
?????????? http://www.springframework.org/schema/context/spring-context-2.5.xsd
?????????? http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
?????????? http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
>

????<context:annotation-config?/>
????<context:component-scan?base-package="com.bluesky"?/>

????<tx:annotation-driven?transaction-manager="transactionManager"/>

????<bean?id="sessionFactory"??
??????????? class
="org.springframework.orm.hibernate3.LocalSessionFactoryBean">??
????????
<property?name="configLocation"?value="classpath:hibernate.cfg.xml"?/>??
????????
<property?name="configurationClass"?value="org.hibernate.cfg.AnnotationConfiguration"?/>
????</bean>??

????
<!--?定義事務管理器(聲明式的事務)?-->??
????
<bean?id="transactionManager"
??????? class="org.springframework.orm.hibernate3.HibernateTransactionManager">
????????<property?name="sessionFactory"?ref="sessionFactory"?/>
????</bean>
????
</beans>

此時在DAO上需加上@Transactional注解,如下:

package?com.bluesky.spring.dao;

import?java.util.List;

import?org.hibernate.SessionFactory;
import?org.springframework.beans.factory.annotation.Autowired;
import?org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import?org.springframework.stereotype.Component;

import?com.bluesky.spring.domain.User;

@Transactional
@Component(
"userDao")
public?class?UserDaoImpl?extends?HibernateDaoSupport?implements?UserDao {

????
public?List<User>?listUsers() {
????????
return?this.getSession().createQuery("from User").list();
??? }
????
????
}
spring里面事務的傳播屬性和事務隔離級別

?

?

?

一、Propagation (事務的傳播屬性)

Propagation :  key屬性確定代理應該給哪個方法增加事務行為。這樣的屬性最重要的部份是傳播行為。有以下選項可供使用:??

PROPAGATION_REQUIRED--支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。

PROPAGATION_SUPPORTS--支持當前事務,如果當前沒有事務,就以非事務方式執行。

PROPAGATION_MANDATORY--支持當前事務,如果當前沒有事務,就拋出異常。

PROPAGATION_REQUIRES_NEW--新建事務,如果當前存在事務,把當前事務掛起。

PROPAGATION_NOT_SUPPORTED--以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。

PROPAGATION_NEVER--以非事務方式執行,如果當前存在事務,則拋出異常。

1: PROPAGATION_REQUIRED

加入當前正要執行的事務不在另外一個事務里,那么就起一個新的事務

比如說,ServiceB.methodB的事務級別定義為PROPAGATION_REQUIRED, 那么由于執行ServiceA.methodA的時候,

ServiceA.methodA已經起了事務,這時調用ServiceB.methodB,ServiceB.methodB看到自己已經運行在ServiceA.methodA

的事務內部,就不再起新的事務。而假如ServiceA.methodA運行的時候發現自己沒有在事務中,他就會為自己分配一個事務。

這樣,在ServiceA.methodA或者在ServiceB.methodB內的任何地方出現異常,事務都會被回滾。即使ServiceB.methodB的事務已經被

提交,但是ServiceA.methodA在接下來fail要回滾,ServiceB.methodB也要回滾

2: PROPAGATION_SUPPORTS

如果當前在事務中,即以事務的形式運行,如果當前不再一個事務中,那么就以非事務的形式運行

3: PROPAGATION_MANDATORY

必須在一個事務中運行。也就是說,他只能被一個父事務調用。否則,他就要拋出異常

4: PROPAGATION_REQUIRES_NEW

這個就比較繞口了。 比如我們設計ServiceA.methodA的事務級別為PROPAGATION_REQUIRED,ServiceB.methodB的事務級別為PROPAGATION_REQUIRES_NEW,

那么當執行到ServiceB.methodB的時候,ServiceA.methodA所在的事務就會掛起,ServiceB.methodB會起一個新的事務,等待ServiceB.methodB的事務完成以后,

他才繼續執行。他與PROPAGATION_REQUIRED 的事務區別在于事務的回滾程度了。因為ServiceB.methodB是新起一個事務,那么就是存在

兩個不同的事務。如果ServiceB.methodB已經提交,那么ServiceA.methodA失敗回滾,ServiceB.methodB是不會回滾的。如果ServiceB.methodB失敗回滾,

如果他拋出的異常被ServiceA.methodA捕獲,ServiceA.methodA事務仍然可能提交。

5: PROPAGATION_NOT_SUPPORTED

當前不支持事務。比如ServiceA.methodA的事務級別是PROPAGATION_REQUIRED ,而ServiceB.methodB的事務級別是PROPAGATION_NOT_SUPPORTED ,

那么當執行到ServiceB.methodB時,ServiceA.methodA的事務掛起,而他以非事務的狀態運行完,再繼續ServiceA.methodA的事務。

6: PROPAGATION_NEVER

不能在事務中運行。假設ServiceA.methodA的事務級別是PROPAGATION_REQUIRED, 而ServiceB.methodB的事務級別是PROPAGATION_NEVER ,

那么ServiceB.methodB就要拋出異常了。

7: PROPAGATION_NESTED

理解Nested的關鍵是savepoint。他與PROPAGATION_REQUIRES_NEW的區別是,PROPAGATION_REQUIRES_NEW另起一個事務,將會與他的父事務相互獨立,

而Nested的事務和他的父事務是相依的,他的提交是要等和他的父事務一塊提交的。也就是說,如果父事務最后回滾,他也要回滾的。

而Nested事務的好處是他有一個savepoint。

*****************************************

ServiceA {

/**

* 事務屬性配置為 PROPAGATION_REQUIRED

*/

void methodA() {

try {

//savepoint

ServiceB.methodB(); //PROPAGATION_NESTED 級別

} catch (SomeException) {

// 執行其他業務, 如 ServiceC.methodC();

}

}

}

********************************************

也就是說ServiceB.methodB失敗回滾,那么ServiceA.methodA也會回滾到savepoint點上,ServiceA.methodA可以選擇另外一個分支,比如

ServiceC.methodC,繼續執行,來嘗試完成自己的事務。

但是這個事務并沒有在EJB標準中定義。

二、Isolation Level(事務隔離等級):

1、Serializable:最嚴格的級別,事務串行執行,資源消耗最大;

2、REPEATABLE READ:保證了一個事務不會修改已經由另一個事務讀取但未提交(回滾)的數據。避免了“臟讀取”和“不可重復讀取”的情況,但是帶來了更多的性能損失。

3、READ COMMITTED:大多數主流數據庫的默認事務等級,保證了一個事務不會讀到另一個并行事務已修改但未提交的數據,避免了“臟讀取”。該級別適用于大多數系統。

4、Read Uncommitted:保證了讀取過程中不會讀取到非法數據。隔離級別在于處理多事務的并發問題。

我們知道并行可以提高數據庫的吞吐量和效率,但是并不是所有的并發事務都可以并發運行,這需要查看數據庫教材的可串行化條件判斷了。

這里就不闡述。

我們首先說并發中可能發生的3中不討人喜歡的事情

1: Dirty reads--讀臟數據。也就是說,比如事務A的未提交(還依然緩存)的數據被事務B讀走,如果事務A失敗回滾,會導致事務B所讀取的的數據是錯誤的。

2: non-repeatable reads--數據不可重復讀。比如事務A中兩處讀取數據-total-的值。在第一讀的時候,total是100,然后事務B就把total的數據改成 200,事務A再讀一次,結果就發現,total竟然就變成200了,造成事務A數據混亂。

3: phantom reads--幻象讀數據,這個和non-repeatable reads相似,也是同一個事務中多次讀不一致的問題。但是non-repeatable reads的不一致是因為他所要取的數據集被改變了(比如total的數據),但是phantom reads所要讀的數據的不一致卻不是他所要讀的數據集改變,而是他的條件數據集改變。比如Select account.id where account.name="ppgogo*",第一次讀去了6個符合條件的id,第二次讀取的時候,由于事務b把一個帳號的名字由"dd"改成"ppgogo1",結果取出來了7個數據。

?

?

?Dirty readsnon-repeatable readsphantom reads
Serializable不會不會不會
REPEATABLE READ不會不會
READ COMMITTED不會
Read Uncommitted

?

?

三、readOnly

事務屬性中的readOnly標志表示對應的事務應該被最優化為只讀事務。

這是一個最優化提示。在一些情況下,一些事務策略能夠起到顯著的最優化效果,例如在使用Object/Relational映射工具(如:Hibernate或TopLink)時避免dirty checking(試圖“刷新”)。

四、Timeout

在事務屬性中還有定義“timeout”值的選項,指定事務超時為幾秒。在JTA中,這將被簡單地傳遞到J2EE服務器的事務協調程序,并據此得到相應的解釋

?

spring里面事務的傳播屬性和事務隔離級別

?

?

一、Propagation (事務的傳播屬性)

Propagation :  key屬性確定代理應該給哪個方法增加事務行為。這樣的屬性最重要的部份是傳播行為。有以下選項可供使用:PROPAGATION_REQUIRED--支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。

PROPAGATION_SUPPORTS--支持當前事務,如果當前沒有事務,就以非事務方式執行。

PROPAGATION_MANDATORY--支持當前事務,如果當前沒有事務,就拋出異常。

PROPAGATION_REQUIRES_NEW--新建事務,如果當前存在事務,把當前事務掛起。

PROPAGATION_NOT_SUPPORTED--以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。

PROPAGATION_NEVER--以非事務方式執行,如果當前存在事務,則拋出異常。

1: PROPAGATION_REQUIRED

加入當前正要執行的事務不在另外一個事務里,那么就起一個新的事務

比如說,ServiceB.methodB的事務級別定義為PROPAGATION_REQUIRED, 那么由于執行ServiceA.methodA的時候,

ServiceA.methodA已經起了事務,這時調用ServiceB.methodB,ServiceB.methodB看到自己已經運行在ServiceA.methodA

的事務內部,就不再起新的事務。而假如ServiceA.methodA運行的時候發現自己沒有在事務中,他就會為自己分配一個事務。

這樣,在ServiceA.methodA或者在ServiceB.methodB內的任何地方出現異常,事務都會被回滾。即使ServiceB.methodB的事務已經被

提交,但是ServiceA.methodA在接下來fail要回滾,ServiceB.methodB也要回滾

2: PROPAGATION_SUPPORTS

如果當前在事務中,即以事務的形式運行,如果當前不再一個事務中,那么就以非事務的形式運行

3: PROPAGATION_MANDATORY

必須在一個事務中運行。也就是說,他只能被一個父事務調用。否則,他就要拋出異常

4: PROPAGATION_REQUIRES_NEW

這個就比較繞口了。 比如我們設計ServiceA.methodA的事務級別為PROPAGATION_REQUIRED,ServiceB.methodB的事務級別為PROPAGATION_REQUIRES_NEW,

那么當執行到ServiceB.methodB的時候,ServiceA.methodA所在的事務就會掛起,ServiceB.methodB會起一個新的事務,等待ServiceB.methodB的事務完成以后,

他才繼續執行。他與PROPAGATION_REQUIRED 的事務區別在于事務的回滾程度了。因為ServiceB.methodB是新起一個事務,那么就是存在

兩個不同的事務。如果ServiceB.methodB已經提交,那么ServiceA.methodA失敗回滾,ServiceB.methodB是不會回滾的。如果ServiceB.methodB失敗回滾,

如果他拋出的異常被ServiceA.methodA捕獲,ServiceA.methodA事務仍然可能提交。

5: PROPAGATION_NOT_SUPPORTED

當前不支持事務。比如ServiceA.methodA的事務級別是PROPAGATION_REQUIRED ,而ServiceB.methodB的事務級別是PROPAGATION_NOT_SUPPORTED ,

那么當執行到ServiceB.methodB時,ServiceA.methodA的事務掛起,而他以非事務的狀態運行完,再繼續ServiceA.methodA的事務。

6: PROPAGATION_NEVER

不能在事務中運行。假設ServiceA.methodA的事務級別是PROPAGATION_REQUIRED, 而ServiceB.methodB的事務級別是PROPAGATION_NEVER ,

那么ServiceB.methodB就要拋出異常了。

7: PROPAGATION_NESTED

理解Nested的關鍵是savepoint。他與PROPAGATION_REQUIRES_NEW的區別是,PROPAGATION_REQUIRES_NEW另起一個事務,將會與他的父事務相互獨立,

而Nested的事務和他的父事務是相依的,他的提交是要等和他的父事務一塊提交的。也就是說,如果父事務最后回滾,他也要回滾的。

而Nested事務的好處是他有一個savepoint。

*****************************************

ServiceA {

/**

* 事務屬性配置為 PROPAGATION_REQUIRED

*/

void methodA() {

try {

//savepoint

ServiceB.methodB(); //PROPAGATION_NESTED 級別

} catch (SomeException) {

// 執行其他業務, 如 ServiceC.methodC();

}

}

}

********************************************

也就是說ServiceB.methodB失敗回滾,那么ServiceA.methodA也會回滾到savepoint點上,ServiceA.methodA可以選擇另外一個分支,比如

ServiceC.methodC,繼續執行,來嘗試完成自己的事務。

但是這個事務并沒有在EJB標準中定義。

二、Isolation Level(事務隔離等級):

1、Serializable:最嚴格的級別,事務串行執行,資源消耗最大;

2、REPEATABLE READ:保證了一個事務不會修改已經由另一個事務讀取但未提交(回滾)的數據。避免了“臟讀取”和“不可重復讀取”的情況,但是帶來了更多的性能損失。

3、READ COMMITTED:大多數主流數據庫的默認事務等級,保證了一個事務不會讀到另一個并行事務已修改但未提交的數據,避免了“臟讀取”。該級別適用于大多數系統。

4、Read Uncommitted:保證了讀取過程中不會讀取到非法數據。隔離級別在于處理多事務的并發問題。

我們知道并行可以提高數據庫的吞吐量和效率,但是并不是所有的并發事務都可以并發運行,這需要查看數據庫教材的可串行化條件判斷了。

這里就不闡述。

我們首先說并發中可能發生的3中不討人喜歡的事情

1: Dirty reads--讀臟數據。也就是說,比如事務A的未提交(還依然緩存)的數據被事務B讀走,如果事務A失敗回滾,會導致事務B所讀取的的數據是錯誤的。

2: non-repeatable reads--數據不可重復讀。比如事務A中兩處讀取數據-total-的值。在第一讀的時候,total是100,然后事務B就把total的數據改成 200,事務A再讀一次,結果就發現,total竟然就變成200了,造成事務A數據混亂。

3: phantom reads--幻象讀數據,這個和non-repeatable reads相似,也是同一個事務中多次讀不一致的問題。但是non-repeatable reads的不一致是因為他所要取的數據集被改變了(比如total的數據),但是phantom reads所要讀的數據的不一致卻不是他所要讀的數據集改變,而是他的條件數據集改變。比如Select account.id where account.name="ppgogo*",第一次讀去了6個符合條件的id,第二次讀取的時候,由于事務b把一個帳號的名字由"dd"改成"ppgogo1",結果取出來了7個數據。

?

?

?Dirty readsnon-repeatable readsphantom reads
Serializable不會不會不會
REPEATABLE READ不會不會
READ COMMITTED不會
Read Uncommitted

?

?

三、readOnly

事務屬性中的readOnly標志表示對應的事務應該被最優化為只讀事務。

這是一個最優化提示。在一些情況下,一些事務策略能夠起到顯著的最優化效果,例如在使用Object/Relational映射工具(如:Hibernate或TopLink)時避免dirty checking(試圖“刷新”)。

四、Timeout

在事務屬性中還有定義“timeout”值的選項,指定事務超時為幾秒。在JTA中,這將被簡單地傳遞到J2EE服務器的事務協調程序,并據此得到相應的解釋

?

?

20110112

數據庫提供了四種事務隔離級別, 不同的隔離級別采用不同的鎖類開來實現.?

在四種隔離級別中, Serializable的級別最高, Read Uncommited級別最低.?

大多數數據庫的默認隔離級別為: Read Commited,如Sql Server ,?Oracle.?

少數數據庫默認的隔離級別為Repeatable Read, 如MySQL?InnoDB存儲引擎?

即使是最低的級別,也不會出現 第一類 丟失 更新問題 .??

1.?臟讀(事務沒提交,提前讀取)?:臟讀就是指當一個事務正在訪問數據,并且對數據進行了修改,而這種修改還沒有提交到數據庫中,這時,另外一個事務也訪問這個數據,然后使用了這個數據。

2.?不可重復讀(兩次讀的不一致)?:是指在一個事務內,多次讀同一數據。在這個事務還沒有結束時,另外一個事務也訪問該同一數據。那么,在第一個事務中的兩次讀數據之間,由于第二個事務的修改,那么第一個事務兩次讀到的的數據可能是不一樣的。這樣就發生了在一個事務內兩次讀到的數據是不一樣的,因此稱為是不可重復讀。例如,一個編輯人員兩次讀取同一文檔,但在兩次讀取之間,作者重寫了該文檔。當編輯人員第二次讀取文檔時,文檔已更改。原始讀取不可重復。如果只有在作者全部完成編寫后編輯人員才可以讀取文檔,則可以避免該問題。?
3.?幻讀?: 是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的全部數據行。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那么,以后就會發生操作第一個事務的用戶發現表中還有沒有修改的數據行,就好象發生了幻覺一樣。例如,一個編輯人員更改作者提交的文檔,但當生產部門將其更改內容合并到該文檔的主復本時,發現作者已將未編輯的新材料添加到該文檔中。如果在編輯人員和生產部門完成對原始文檔的處理之前,任何人都不能將新材料添加到文檔中,則可以避免該問題。?
4.?第一類更新丟失(回滾丟失)?:?
? 當2個事務更新相同的數據源,如果第一個事務被提交,而另外一個事務卻被撤銷,那么會連同第一個事務所做的跟新也被撤銷。也就是說第一個事務做的跟新丟失了。?
5.?第二類更新丟失(覆蓋丟失)?:?
? 第二類更新丟失實在實際應用中經常遇到的并發問題,他和不可重復讀本質上是同一類并發問題,通常他被看做不可重復讀的特例:當2個或這個多個事務查詢同樣的記錄然后各自基于最初的查詢結果更新該行時,會造成第二類丟失更新。因為每個事務都不知道不知道其他事務的存在,最后一個事務對記錄做的修改將覆蓋其他事務對該記錄做的已提交的跟新...?
補充 : 基于元數據的 Spring 聲明性事務 :?

Isolation 屬性一共支持五種事務設置,具體介紹如下:?

l????????? DEFAULT 使用數據庫設置的隔離級別 ( 默認 ) ,由 DBA 默認的設置來決定隔離級別 .?

l????????? READ_UNCOMMITTED 會出現臟讀、不可重復讀、幻讀 ( 隔離級別最低,并發性能高 )?

l????????? READ_COMMITTED? 會出現不可重復讀、幻讀問題(鎖定正在讀取的行)?

l????????? REPEATABLE_READ 會出幻讀(鎖定所讀取的所有行)?

l????????? SERIALIZABLE 保證所有的情況不會發生(鎖表)?

不可重復讀的重點是修改 :?
同樣的條件 ,?? 你讀取過的數據 ,?? 再次讀取出來發現值不一樣了?
幻讀的重點在于新增或者刪除?
同樣的條件 ,?? 第 1 次和第 2 次讀出來的記錄數不一樣?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/452007.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/452007.shtml
英文地址,請注明出處:http://en.pswp.cn/news/452007.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Google編程之夏入圍項目公布

Google編程之夏&#xff08;Google Summer of Code&#xff09;&#xff0c;是由Google公司所主辦的年度程式設計比賽&#xff0c;第一屆從2005年開始。“Summer of Code”之名取自1967年的“夏日之愛”&#xff08;Summer of Love&#xff09;風潮。比賽的主要目的是鼓勵學生參…

普通索引 唯一索引 主鍵索引 候選索引

普通索引 最基本的索引類型&#xff0c;沒有唯一性之類的限制。普通索引可以通過以下幾種方式創建&#xff1a; 創建索引&#xff0c;例如CREATE INDEX <索引的名字> ON tablename (列的列表)&#xff1b; 修改表&#xff0c;例如ALTER TABLE tablename ADD INDEX [索引…

Android 基于注解IOC組件化/模塊化的架構實踐

當前參與的項目歷史也很久遠&#xff0c;第一行代碼據說是寫于2014年的某一天&#xff0c;那時Android用的ide還是Eclipse、那時Android還沒有很好的架構指導&#xff08;mvp、mvvm&#xff09;、那時Android最新的版本是5.0、那時Android的Material Design還沒流行……背景隨著…

網絡爬蟲--14.【糗事百科實戰】

文章目錄一. 要求二. 參考代碼一. 要求 爬取糗事百科段子&#xff0c;假設頁面的URL是 http://www.qiushibaike.com/8hr/page/1 使用requests獲取頁面信息&#xff0c;用XPath / re 做數據提取 獲取每個帖子里的用戶頭像鏈接、用戶姓名、段子內容、點贊次數和評論次數 保存到…

bzoj 5369: [Pkusc2018]最大前綴和

Description 小C是一個算法競賽愛好者&#xff0c;有一天小C遇到了一個非常難的問題&#xff1a;求一個序列的最大子段和。 但是小C并不會做這個題&#xff0c;于是小C決定把序列隨機打亂&#xff0c;然后取序列的最大前綴和作為答案。 小C是一個非常有自知之明的人&#xff0c…

微軟:軟件帝王的復興之路

可以說在過去的兩個月IT界所發生的一切都非同尋常&#xff0c;喬布斯辭職了&#xff0c;Google把Motorola并購了&#xff0c;微軟炫了一下Windows 8&#xff0c;還宣布開始用ARM了&#xff0c;Google開始和英特爾合作了&#xff0c;AT&T與T-Mobile的并購也在緊密鑼鼓進行中…

jdbc和odbc區別

ODBC(Open Database Connectivity&#xff0c;開放數據庫互連)是微軟公司開放服務結構(WOSA&#xff0c;Windows Open Services Architecture)中有關數據庫的一個組成部分&#xff0c;它建立了一組規范&#xff0c;并提供了一組對數據庫訪問的標準API&#xff08;應用程序編程接…

事務相關、不可重復讀與幻讀的區別

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 事務內嵌套事務&#xff1a; 1) 都用spring事務時&#xff0c;取決spring采用的事務的隔離級別。 這個默認隔離級別是與具體的數據…

onload事件

onload事件它只支持少量標簽<body>, <frame>, <iframe>, <img>, <input type"image">, <link>, <script>, <style> 不支持<div>,<p>標簽等 所以&#xff0c;在div使用onload事件時該怎么辦呢。。。轉載…

Eclipse GBK批量轉UTF-8插件(轉)

最近需要把Android項目轉Android Studio&#xff0c;由于之前是eclipse開發&#xff0c;而且坑爹的是編碼還是GBK的&#xff0c;轉到Android Studio中文都是亂碼&#xff0c;如果一個文件一個文件ctrlc的話&#xff0c;想想就累&#xff0c;幾經Google&#xff0c;發現一個很好…

網絡爬蟲--15.【糗事百科實戰】多線程實現

文章目錄一. Queue&#xff08;隊列對象&#xff09;二. 多線程示意圖三. 代碼示例一. Queue&#xff08;隊列對象&#xff09; Queue是python中的標準庫&#xff0c;可以直接import Queue引用;隊列是線程間最常用的交換數據的形式 python下多線程的思考 對于資源&#xff0…

淺談:國內軟件公司為何無法做大做強?

縱覽,國內比較大的軟件公司(以下統一簡稱"國軟"),清一色都是做政府項目的(他們能做大的原因我就不用說了吧),真正能做大的國軟又有幾家呢?這是為什么呢? 今天風吹就給大家簡單分析下: 1."作坊"式管理 "作坊"往往是效率最高的,國軟幾乎都是從作…

Java SE、Java EE、Java ME三者的區別

說得簡單點 Java SE 是做電腦上運行的軟件。 Java EE 是用來做網站的-&#xff08;我們常見的JSP技術&#xff09; Java ME 是做手機軟件的。 1. Java SE&#xff08;Java Platform&#xff0c;Standard Edition&#xff09;。Java SE 以前稱為 J2SE。它允許開發和部署在桌面、…

FileBeats安裝

FileBeats安裝 FileBeats官方下載鏈接&#xff1a; https://www.elastic.co/downloads/beats/filebeat 也可以直接使用以下命令下載&#xff08;文章下載目錄一概為/home/tools, 解壓后文件夾放到 /home/apps下&#xff09; wget https://artifacts.elastic.co/downloads/beats…

《程序員代碼面試指南》第三章 二叉樹問題 二叉樹節點間的最大距離問題

題目 二叉樹節點間的最大距離問題 java代碼 package com.lizhouwei.chapter3;/*** Description:二叉樹節點間的最大距離問題* Author: lizhouwei* CreateDate: 2018/4/16 19:33* Modify by:* ModifyDate:*/ public class Chapter3_20 {public int maxDistance(Node head) {int[…

MySQL中函數CONCAT及GROUP_CONCAT 對應oracle中的wm_concat

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 一、CONCAT&#xff08;&#xff09;函數 CONCAT&#xff08;&#xff09;函數用于將多個字符串連接成一個字符串。 使用數據表Info作為…

網絡爬蟲--16.BeautifulSoup4

文章目錄一. BeautifulSoup4二. 解析實例三. 四大對象種類1. Tag2. NavigableString3. BeautifulSoup4. Comment四. 遍歷文檔樹1.直接子節點 &#xff1a;.contents .children 屬性1). .contents2). .children2. 所有子孫節點: .descendants 屬性3. 節點內容: .string 屬性五. …

Intel MKL 多線程設置

對于多核程序&#xff0c;多線程對于程序的性能至關重要。 下面&#xff0c;我們將對Intel MKL 有關多線程方面的設置做一些介紹&#xff1a; 我們提到MKL 支持多線程&#xff0c;它包括的兩個概念&#xff1a; 1>MKL 是線程安全的&#xff1a; MKL在設計時&#xff0c;就保…

【LA3415 訓練指南】保守的老師 【二分圖最大獨立集,最小割】

題意 Frank是一個思想有些保守的高中老師。有一次&#xff0c;他需要帶一些學生出去旅行&#xff0c;但又怕其中一些學生在旅行中萌生愛意。為了降低這種事情發生的概率&#xff0c;他決定確保帶出去的任意兩個學生至少要滿足下面四條中的一條。 1.身高相差大于40厘米 2.性別相…

行車記錄儀穩定方案:TC358778XBG:RGB轉MIPI DSI芯片,M-Star標配IC

原廠&#xff1a;Toshiba型號&#xff1a;TC358778XBG功能&#xff1a;TC358778XBG是一顆將RGB信號轉換成MIPI DSI的芯片&#xff0c;最高分辨率支持到1920x1200&#xff0c;其應用圖如下&#xff1a;產品特征&#xff1a;MIPI接口&#xff1a;&#xff08;1&#xff09;、支持…