事務傳播機制/數據庫異常解析——2016-8-13分享總結

一. 事務的傳播機制/required 跟 required new 的使用與區別

基礎回顧

1.1 事務的隔離級別

  ISOLATION_READ_UNCOMMITTED(讀未提交)

  ISOLATION_READ_COMMITTED(讀已提交)

  ISOLATION_REPEATABLE_READ(可重復讀)

  ISOLATION_SERIALIZABLE(序列化)    

  ISOLATION_DEFAULT(使用數據庫默認隔離級別)

1.2 臟讀,不可重復讀以及幻讀

  臟讀:一個事務讀取到另一事務未提交的更新新據。

  不可重復讀:在同一事務中,多次讀取同一數據返回的結果有所不同。換句話說就是,后續讀取可以讀到另一事務已提交的更新數據。

  幻讀:事務1正常查詢一次,之后事務2插入滿足事務1查詢條件的新行,再次用事務1查詢,得到多出來的數據。

1.3 事務的傳播屬性

  PROPAGATION_REQUIRED: ?支持當前事務,沒有則新建

  PROPAGATION_REQUIRESNEW: ?新建事務,如果當前存在事務,把當前事務掛起

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

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

  PROPAGATION_NOT_SUPPORTED:以非事務方式執行,如果當前存在事務,就把當前事務掛起。也就是說業務方法不需要事務

  PROPAGATION_NEVER:以非事務方式執行,如果當前存在事務,則拋出異常。也就是說業務方法絕對不能在事務范圍內執行

  PROPAGATION_NESTED:如果一個活動的事務存在,則運行在一個嵌套的事務中。 如果沒有活動事務, 則按REQUIRED屬性執行  

二. 事務的回滾及傳播機制總結

  1. 首先要注意的是 spring 的默認回滾,roll-back = “runtimeException”,即 spring 只回滾接收到的運行時異常,對于其他異常則不回滾;

  源碼解析:

/*** Handle a throwable, completing the transaction.* We may commit or roll back, depending on the configuration.* @param txInfo information about the current transaction* @param ex throwable encountered*/protected void completeTransactionAfterThrowing(TransactionInfo txInfo, Throwable ex) {if (txInfo != null && txInfo.hasTransaction()) {if (logger.isTraceEnabled()) {logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +"] after exception: " + ex);}if (txInfo.transactionAttribute.rollbackOn(ex)) {try {txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());}catch (TransactionSystemException ex2) {logger.error("Application exception overridden by rollback exception", ex);ex2.initApplicationException(ex);throw ex2;}
...

  注意上述有一段是?txInfo.transactionAttribute.rollbackOn(ex) 方法,跟進此方法:

/*** The default behavior is as with EJB: rollback on unchecked exception.* Additionally attempt to rollback on Error.* <p>This is consistent with TransactionTemplate's default behavior.*/public boolean rollbackOn(Throwable ex) {return (ex instanceof RuntimeException || ex instanceof Error);}

  所以,默認不修改的話,只回滾 RuntimeException 或者 Error

  2. 對此我們可以針對性的添加需要回滾的策略,或者直接顯示設置 roll-back = “Exception”,即回滾所有異常;

  3. 需要注意的是:普通情況下,如果異常被 try-catch 處理了,并為進一步拋出異常,那么由于 spring 并未接受到異常, 所以也不會回滾;

  ?本周討論補充知識:

  4. 異常分為 應用層拋出 的異常,以及 數據庫 的異常,如果是前者,可以正常應用 spring 的事務傳播規則,如果是后者,那么一旦發生,數據庫端就已經放棄事務,也就沒有回滾一說();

  例: int 10/0 為應用層的異常,可以正常回滾; insert 提交一個已存在的 唯一字段,那么數據庫會報錯,由于事務本身也是由 spring 告之數據庫處理,這種情況下,由于 數據庫已經放棄事務,那么 spring 層面也不能進行事務回滾;

  5. 正常情況下不會出現一個接口的 bean 進行嵌套調用,如果有,該情況下,由于代理類不再使用 spring 動態代理中的接口實現的方式,而是采用 cglib 的繼承實現方式,同樣也會導致傳播失效;

  6. 事務的傳播機制較為常用的為:required,required-new,support。討論結果為 required-new 跟 required 相比,使用應較為謹慎,原因:同一事務粒度更細更可控,同時也能避免 嵌套事務 可能導致的復雜情況,當然,具體情況需要根據具體業務來定,比如本次討論中的項目,由于每一次操作的對象都要及時被可能存在的另一進程知悉,這種情況下需要 required-new 來實時開啟事務告之其他進程;

  查詢總結過程中發現的其它知識點

  1. 注意的小點,MySQL 中 InnoDB 支持事務,MyIsam 并不支持事務;

  2. spring 已經提供了異常處理機制,其基類為?DataAccessException ,它是 RuntimeExcption 的一個子類,據此可以知道,所有從 數據庫返回的異常,都會被 spring 處理后 歸屬于 RuntimeException 中,其體系如下:

  

2. 在?org.springframework.jdbc.support包下有sql-error-codes.xml文件,里面預定義了一些錯誤代碼和信息,其 bean 為 HSQL,在 第8行,我們可以發現重復插入的 code 為 -104;

  bean id="HSQL" class="org.springframework.jdbc.support.SQLErrorCodes"    property name="databaseProductName"     valueHSQL Database Engine/value     /property     property name="badSqlGrammarCodes"     value-22,-28/value     /property     property name="duplicateKeyCodes"     value-104/value     /property     property name="dataIntegrityViolationCodes"     value-9/value     /property     property name="dataAccessResourceFailureCodes"     value-80/value     /property     /bean     

  3. 此外,我們可以知道發散性的看,我們完全可以自定義數據庫異常的信息,方法如下:

  3.1?重新新建一個sql-error-codes.xml代碼,并將它放到類路徑的根目錄下,這樣Spring會發現它并使用我們自定義的文件。同時HSQL的bean的名稱不要改,并將useSqlStateForTranslation置為false,就可以使用我們自己定義的異常類;

bean id="HSQL" class="org.springframework.jdbc.support.SQLErrorCodes"     property name="databaseProductName" value="HSQL Database Engine" /     property name="useSqlStateForTranslation" value="false" /     property name="customTranslations"     list     ref local="vehicleDuplicateKeyTranslation" /     /list     /property     /bean     
bean id="vehicleDuplicateKeyTranslation"     class="org.springframework.jdbc.support.CustomSQLErrorCodesTranslation"     property name="errorCodes" value="-104" /     property name="exceptionClass" value="org.ourpioneer.vehicle.exception.VehicleDuplicateKeyException" /     /bean 

  3.2 可以看到結果,控制臺所打印的異常類型為我們自己定義的異常類型;

  3.3?除此之外,還可以實現SQLExceptionTranslator接口,并在JDBC模板中注入其實例來實現異常控制

   1. package org.ourpioneer.vehicle.exception;      2. import java.sql.SQLException;      3. import org.springframework.dao.DataAccessException;      4. import org.springframework.jdbc.UncategorizedSQLException;      5. import org.springframework.jdbc.support.SQLExceptionTranslator;      6. public class VehicleDuplicateKeyTranslator implements SQLExceptionTranslator {      7.     public DataAccessException translate(String task, String sql,      8.             SQLException ex) {      9.         if (task == null) {      10.             task = "";      11.         }      12.         if (sql == null) {      13.         }      14.         if (ex.getErrorCode() == -104) {      15.             return new VehicleDuplicateKeyException(buildMessage(task, sql, ex));      16.         } else {      17.             return new UncategorizedSQLException(task, sql, ex);      18.         }      19.     }      20.     private String buildMessage(String task, String sql, SQLException ex) {      21.         return "數據庫操作異常:" + task + "; SQL [" + sql + "]; " + ex.getMessage();      22.     }      23. } 

  3.4?translate方法有三個參數,task表示當前操作要進行的任務是什么,sql就是執行的sql語句,ex表示SQLException,我們可以從中獲取異常信息,其處理代碼僅僅捕捉了錯誤碼為-104(HSQL數據庫)的錯誤,其余的配置信息可以根據需要來自行添加。之后要在Spring中重新配置它們:

   1. bean id="vehicleDuplicateKeyTranslator"     2. class="org.ourpioneer.vehicle.exception.VehicleDuplicateKeyTranslator"/bean     3. bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"     4.     property name="exceptionTranslator" ref="vehicleDuplicateKeyTranslator" /     5.     property name="dataSource" ref="dataSource" /     6. /bean     7. bean id="vehicleDAO" class="org.ourpioneer.vehicle.dao.VehicleDAOImpl"     8.     property name="jdbcTemplate" ref="jdbcTemplate" /     9. /bean 

  3.5 測試結果

?

三. 總結

  其實之前對事務的理解是比較基礎的,經過周六的交流和學習,才對事務有了略深一層的理解,但同時也愈發覺得事務的博大精深應遠不止于此,本文大部分都是結合各位?同事的理解和網上的一些資料整理的文章,所以本文作用更多的督促自己的學習進步,希望以后自己能不斷的吸收,整理和提煉知識?。

?

參考文獻:

mysql隔離級別及事務傳播:https://gist.github.com/JagoWang/4555317

mysql事務管理及spring聲明式事務中主動異常拋出使數據庫回滾:http://www.cnblogs.com/wanglonghai/p/4866512.html

Spring訪問數據庫異常的處理方法:http://kb.cnblogs.com/page/89216/

轉載于:https://www.cnblogs.com/Mr-Persist/p/5773314.html

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

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

相關文章

console類詳細解釋

console類詳細解釋 微軟鏈接https://docs.microsoft.com/zh-cn/dotnet/api/system.console?viewnetframework-4.8 C#中沒有標準輸入輸出關鍵字&#xff0c;要調用console類下的方法。 練習與解釋代碼 using System; using System.Collections.Generic; using System.Linq; …

VC下調用x264進行視頻編碼,

4.X264.c中,h x264_encoder_open( param ) )是用來復制參數并驗證參數的有效性,在CCS下應該是不需要驗證參數的(參數都是在程序中設置好的),因此此處只作復制參數param和初始化X264_T h的操作.(VC下程序修改記錄080106下午)修改COMMON.C中的void x264_param_default( x264_…

UploadRTOS.exe

UploadRTOS.exe類似于一個啟動并為VxWin運行做準備的工具程序。VxWin安裝之后&#xff0c;可以使用 上傳工具程序 啟動實時操作系統。 利用命令行參數,您可以使它執行不同的功能。該 上傳工具程序 包含兩個文件: UploadRTOS.exe (命令行程序) UploadR…

20155307 2016-2017 《Java程序設計》第三次實驗報告

&#xff08;一&#xff09;敏捷開發與XP 敏捷開發是一種以人為核心、迭代、循序漸進的開發方法。“敏捷流程”是一系列價值觀和方法論的集合。從2001年開始&#xff0c;一些軟件界的專家開始倡導“敏捷”的價值觀和流程&#xff0c;他們肯定了流行做法的價值&#xff0c;但是強…

ElasticSearch創建、修改、獲取、刪除、索引Indice mapping和Index Template案例

為什么80%的碼農都做不了架構師&#xff1f;>>> The best elasticsearch highlevel java rest api-----bboss ElasticSearch客戶端框架bboss的ClientInterface 接口提供了創建/修改、獲取、刪除索引Indice和IndexTemplate的方法&#xff0c;本文舉例說明其使用方法…

ASCII碼與string的相互轉換

ASCII碼與string的相互轉換 思路&#xff1a; 1&#xff09;ASCII碼轉string&#xff1a;把字符&#xff08;串&#xff09;直接轉換為int類型&#xff0c;即可得到ASCII碼&#xff1b; 2&#xff09;string轉ASCII碼&#xff1a;將數字轉換為字符串轉出&#xff1b; {//將字…

X264代碼中一些參數的意義

Main&#xff08;int argc&#xff0c;char *argv[]&#xff09;; 為了方便起見&#xff0c;不妨改寫為&#xff1a; Main(void){ ...... intargc5; char*argv[]{ "main","-o","test.264","foreman.yuv","352x288" }; …

spring mvc注解@RequestMapping

1、url路徑映射 基本功能 2、窄化請求映射 根路徑子路徑 注意setViewName的路徑。 3、限制http請求方法 get和 post 如果是get 轉載于:https://www.cnblogs.com/jway1101/p/5773923.html

Start application automatically during controller boot-up

&#xfeff;&#xfeff; Tip English ?German Start application automatically during controller boot-up Description It is possible to start any program automatically during the boot-up procedure of the KR C4 controller. Precondition ?User group “Exper…

C#using static

平常用法&#xff1a; using 命名空間&#xff1b; using System; Console.WriteLine("Hello&#xff0c;World&#xff01;");using static用法&#xff1a; C#6中支持這種寫法&#xff0c;這樣定義后可以可以訪問類的靜態成員 WriteLine是Console類的靜態函數&am…

redis數據遷移

一&#xff1a;AOF方式 需求&#xff1a; 一個沒有數據的redis。 清空redis數據方法 bash> echo "keys *" | redis-cli --raw -p 6378 |sed -r s/(.*)/redis-cli --raw -p 6378 del \1 /g |bash 1.備份 bash> redis-cli --raw -p 6378 redis> config get di…

阿里云OSS 上傳文件SDK

Aliyun OSS SDK for C# 上傳文件 另外&#xff1a;查找的其他實現C#上傳文件功能例子&#xff1a; 1、WPF用流的方式上傳/顯示/下載圖片文件(保存在數據庫) &#xff08;文末有案例下載鏈接&#xff09; 2、WPF中利用WebClient向服務器上傳文件 3、C#文件上傳的簡單實現 4、C#實…

關于level_idc和Profile_IDC的解釋

2010-01-21 15:51:40| 分類&#xff1a; windows mobile開 |字號 訂閱 Description: Set bitstream Profile IDC. Default is 88. Note: Some profiles cannot support certain features. See MPEG-4 AVC for supported features for each profile. Reference software may…

老婆的駕照要下來了,形容下我此刻的心情

&#xfeff;&#xfeff; 老婆的駕照要下來了&#xff0c;形容下我此刻的心情&#xff1a; 路上遇到的女人&#xff0c;大部分是不用眼睛和腦子開車的&#xff0c;完全是憑自己的感覺開車。凡是看到前車奇慢、路口猶豫不決、不打燈緩慢變線、不該…

ADO.NET改進防注入

static void Main1(string[] args) { //用戶輸入一個需要查詢的條件 car表 Console.WriteLine("請輸入"); string code Console.ReadLine(); SqlConnection conn new SqlConnection("server.;databasemydb;usersa;pwd100867"); SqlCommand cmd conn.Crea…

poj 2139

Floyd-Warshall模板題&#xff0c;我才剛學最短路。。。。 #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int maxn30050; int d[maxn][maxn]; int v,m,n; int a[maxn]; const int inf0…

C#使用了未賦值的局部變量

錯誤原因&#xff1a; 我們先看下例子&#xff1a; int A; Console.WriteLine("數字&#xff1a;{0:d}", A);//在控制臺輸出文本這時提示錯誤&#xff1a;錯誤 1 使用了未賦值的局部變量“A” 原因是C#在使用變量前必須要進行初始化。 解決 解決方案有兩個 1、在…

EtherCAT伺服驅動器-如何選擇硬件開發方案

&#xfeff;&#xfeff;EtherCAT伺服驅動器-如何選擇硬件開發方案

Codevs 1689 建造高塔

1689 建造高塔時間限制: 1 s空間限制: 128000 KB題目等級 : **鉆石 Diamond** 題目描述 Description n有n種石塊&#xff0c;石塊能無限供應。每種石塊都是長方體&#xff0c;其中第i種石塊的長、寬、高分別為li、wi、hi。石塊可以旋轉&#xff0c;使得其中兩維成為長度和寬度&…

windows環境下OpenLDAP安裝與客戶端連接配置

2019獨角獸企業重金招聘Python工程師標準>>> 1.下載安裝OpenLDAP版本 C:\Users\Administrator>slapd -V OpenLDAP 2.4.42 Standalone LDAP Server (slapd) 2.安裝過程中&#xff0c;全部用默認的操作執行即可。 3.修改OpenLDAP文件如下&#xff1a; # MDB Backen…