數據庫事務
數據庫事務(Database Transaction) ,是指作為單個邏輯工作單元執行的一系列操作,
要么完全地執行,要么完全地不執行。
一個邏輯工作單元要成為事務,必須滿足所謂的ACID(原子性、一致性、隔離性和持久性)屬性。
原子性 (Atomic)
事務必須是原子工作單元;對于其數據修改,要么全都執行,要么全都不執行。(整體)
一致性(Consistent)
事務在完成時,必須使所有的數據都保持一致狀態。(完成)
隔離性(Insulation)
由并發事務所做的修改必須與任何其它并發事務所做的修改隔離。(并發)
持久性(Duration)
事務完成以后,它對于系統的影響是永久性的。該修改即使出現致命的系統故障已將一直保持。(結果)
隔離問題
臟讀
一個事務讀到另一個事務沒有提交的數據。
不可重復讀
一個事務讀取到另一個事務已提交的數據(update)。
虛度(幻讀)
一個事務讀取到另一個事務已提交的數據(insert)。
隔離級別
- read uncommitted: 讀未提交。存在以上3個問題。
- read committed:讀已提交。解決臟讀,存在2個問題。
- repeatable read: 可重復讀。解決:臟讀,不可重復讀,存在1個問題。
- serializable: 串行化。都解決,單事務。
mysql事物操作
Connection conn = null;
try{
//1 數據庫鏈接
conn = ...
//2 開啟事物
conn.setAutoCommit(false);
操作A
操作B
操作C
操作D
//3 提交事務
conn.commit();
} catche() {
//4 回滾事務
conn.rollback();
}
mysql事務操作保存點(Savepoint)
Connection conn = null;
//保存點,記錄操作的當前位置,之后可以回滾到指定的位置.(可以回滾一部分)
Savepoint savepoint = null;
try{
//1 數據庫鏈接
conn = ...
//2 開啟事物
conn.setAutoCommit(false);
操作A
操作B
savepoint = conn.setSavepoint();
操作C
操作D
//3 提交事務
conn.commit();
} catche() {
//4 回滾事務
if(savepoint != null) { // CD異常
//回滾到CD之前
conn.rollback(savepoint)
//提交AB
conn.commit();
} else {
//回滾AB
conn.rollback();
}
}
spring 事物管理介紹
添加jar包 spring-tx-4.3.5.RELEASE.jar。
- PlatformTranscationManager 平臺事物管理器,spring 要管理事務,必須使用事物管理器。
進行事務配置時,必須配置事物管理器。 - TransactionDefinition:事物詳情(事務定義,事務屬性),spring用于確定事物具體詳情,例如
隔離級別,是否讀取,超時等。
進行事物配置時,必須配置詳情。spring 將配置項封裝到該對象實例。 - TransactionStatus: 事務狀態,spring用于記錄當前事務運行狀態。
是否有保存點,事務是否完成。
PlatformTransactionManager 事務管理器
導入jar包:需要平臺事物管理器的實現類。
- spring-jdbc-4.3.5.RELEASE.jar jdbc開發
- spring-orm-4.3.5.RELEASE 整合hibernate
常見的事物管理器
DataSourceTransactionManager jdbc開發時事物管理器,采用JdbcTemplate。
HibernateTransactionManager hibernate開發時事物管理器,整合hibernate。
- api方法
TransactionStatus getTransaction(TransactionDefinition var1) 事務管理器 通過“事務詳情”,獲得“事物狀態”,從而管理事務。
void commit(TransactionStatus status) 根據狀態提交
void rollback(TransactionStatus status) 根據狀態回滾
TransactionStatus 事務狀態
- boolean isNewTransaction(); 是否是新事物
- boolean hasSavepoint(); 是否有保存點
- void setRollbackOnly(); 設置回滾
- boolean isRollbackOnly(); 是否回滾
- void flush(); 刷新
- boolean isCompleted(); 是否完成
TransactionDefinition 事物詳情(事務定義,事務屬性)
//傳播行為
int PROPAGATION_REQUIRED = 0;
int PROPAGATION_SUPPORTS = 1;
int PROPAGATION_MANDATORY = 2;
int PROPAGATION_REQUIRES_NEW = 3;
int PROPAGATION_NOT_SUPPORTED = 4;
int PROPAGATION_NEVER = 5;
int PROPAGATION_NESTED = 6;
//隔離級別
int ISOLATION_DEFAULT = -1;
int ISOLATION_READ_UNCOMMITTED = 1;
int ISOLATION_READ_COMMITTED = 2;
int ISOLATION_REPEATABLE_READ = 4;
int ISOLATION_SERIALIZABLE = 8;
//默認超時時間。默認值 -1.使用數據庫底層的超時時間
int TIMEOUT_DEFAULT = -1;
int getPropagationBehavior(); 傳播行為
int getIsolationLevel(); 隔離級別
int getTimeout(); 獲得超時時間
boolean isReadOnly(); 是否只讀(增刪改:讀寫; 查詢:只讀)
String getName(); 配置事務詳情名稱。一般方法名稱。例如:save,add* 等。
-
傳播行為:在兩個業務之間如何共享事務。
- PROPAGATION_REQUIRED , required , 必須 【默認值】
支持當前事務,A如果有事務,B將使用該事務。
如果A沒有事務,B將創建一個新的事務。 - PROPAGATION_SUPPORTS ,supports ,支持
支持當前事務,A如果有事務,B將使用該事務。
如果A沒有事務,B將以非事務執行。 - PROPAGATION_MANDATORY,mandatory ,強制
支持當前事務,A如果有事務,B將使用該事務。
如果A沒有事務,B將拋異常。 - PROPAGATION_REQUIRES_NEW , requires_new ,必須新的
如果A有事務,將A的事務掛起,B創建一個新的事務
如果A沒有事務,B創建一個新的事務 - PROPAGATION_NOT_SUPPORTED ,not_supported ,不支持
如果A有事務,將A的事務掛起,B將以非事務執行
如果A沒有事務,B將以非事務執行 - PROPAGATION_NEVER ,never,從不
如果A有事務,B將拋異常
如果A沒有事務,B將以非事務執行 - PROPAGATION_NESTED ,nested ,嵌套
A和B底層采用保存點機制,形成嵌套事務。
- PROPAGATION_REQUIRED , required , 必須 【默認值】
經常使用
PROPAGATION_REQUIRED PROPAGATION_REQUIRES_NEW PROPAGATION_NESTED
事務處理 AOP配置基于xml
- 使用配置 在spring xml 配置aop自動生成代理,進行事物的管理
- 1,配置管理器。
- 2,配置事物詳情。
- 3,配置aop.
xml 配置 applicationContext-tx.xml
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd"
<!--組件掃描-->
<context:component-scan base-package="com.springdemo"></context:component-scan>
<bean id="dataSourceId" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl"
value="jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=UTF-8"></property>
<property name="user" value="root"></property>
<property name="password" value=""></property>
</bean>
<bean id="template" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSourceId"></property>
</bean>
<bean id="accountDaoId" class="com.springdemo.dao.impl.AccountDaoImpl">
<property name="jdbcTemplate" ref="template"></property>
</bean>
<bean id="serviceId" class="com.springdemo.service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDaoId"></property>
</bean>
<!--事務管理-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSourceId"></property>
</bean>
<!--
事務詳情
<tx:attributes> 用于配置事務詳情(屬性屬性)
<tx:method name=""/> 詳情具體配置
propagation 傳播行為 , REQUIRED:必須;REQUIRES_NEW:必須是新的
isolation 隔離級別
-->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<!--事務名稱-->
<tx:method name="transfer" propagation="REQUIRED" isolation="DEFAULT"/>
</tx:attributes>
</tx:advice>
<!--AOP編程,目標類有ABCD(4個連接點),切入點表達式-->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.springdemo.service.impl.AccountServiceImpl.*(..))"></aop:advisor>
</aop:config>
</beans>