激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 淺談Spring中@Transactional事務回滾及示例(附源碼)

淺談Spring中@Transactional事務回滾及示例(附源碼)

2021-03-04 09:44小寶鴿 Java教程

本篇文章主要介紹了淺談Spring中@Transactional事務回滾及示例(附源碼),小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

一、使用場景舉例

在了解@transactional怎么用之前我們必須要先知道@transactional有什么用。下面舉個栗子:比如一個部門里面有很多成員,這兩者分別保存在部門表和成員表里面,在刪除某個部門的時候,假設我們默認刪除對應的成員。但是在執行的時候可能會出現這種情況,我們先刪除部門,再刪除成員,但是部門刪除成功了,刪除成員的時候出異常了。這時候我們希望如果成員刪除失敗了,之前刪除的部門也取消刪除。這種場景就可以使用@transactional事物回滾。

二、checked異常和unchecked異常

這里之所以讓大家清楚checked異常和unchecked異常概念,是因為:

spring使用聲明式事務處理,默認情況下,如果被注解的數據庫操作方法中發生了unchecked異常,所有的數據庫操作將rollback;如果發生的異常是checked異常,默認情況下數據庫操作還是會提交的。

checked異常:

表示無效,不是程序中可以預測的。比如無效的用戶輸入,文件不存在,網絡或者數據庫鏈接錯誤。這些都是外在的原因,都不是程序內部可以控制的。

必須在代碼中顯式地處理。比如try-catch塊處理,或者給所在的方法加上throws說明,將異常拋到調用棧的上一層。

繼承自java.lang.exception(java.lang.runtimeexception除外)。

unchecked異常:

表示錯誤,程序的邏輯錯誤。是runtimeexception的子類,比如illegalargumentexception, nullpointerexception和illegalstateexception。

不需要在代碼中顯式地捕獲unchecked異常做處理。

繼承自java.lang.runtimeexception(而java.lang.runtimeexception繼承自java.lang.exception)。

看下面的異常結構圖或許層次感更加深些:

淺談Spring中@Transactional事務回滾及示例(附源碼)

三、@transactional的使用實例

本實例采用的是eclipse+maven,maven只是作為jar管理,即便不了解的maven的猿友也可以讀懂。

3.1、spring的配置文件

里面必須先配置tx名字空間如下:

淺談Spring中@Transactional事務回滾及示例(附源碼)

為了使用基于@transactional的事務管理,需要在spring中進行如下的配置:

?
1
2
3
4
5
<bean id="apptransactionmanager" class="org.springframework.jdbc.datasource.datasourcetransactionmanager">
   <property name="datasource" ref="datasource" />
  </bean>
 
  <tx:annotation-driven proxy-target-class="false" transaction-manager="apptransactionmanager" />

博主的整個spring配置文件:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<?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:tx="http://www.springframework.org/schema/tx"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xsi:schemalocation="
      http://www.springframework.org/schema/tx
      http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 
   <!-- 引入jdbc配置文件 -->
   <bean id="propertyconfigurer" class="org.springframework.beans.factory.config.propertyplaceholderconfigurer">
    <property name="locations">
      <list>
        <value>classpath:properties/*.properties</value>
        <!--要是有多個配置文件,只需在這里繼續添加即可 -->
      </list>
    </property>
  </bean>
 
  <!-- 配置數據源 -->
  <bean id="datasource"
    class="org.springframework.jdbc.datasource.drivermanagerdatasource">
    <!-- 不使用properties來配置 -->
    <!-- <property name="driverclassname" value="com.mysql.jdbc.driver" />
      <property name="url" value="jdbc:mysql://localhost:3306/learning" />
      <property name="username" value="root" />
      <property name="password" value="christmas258@" /> -->
    <!-- 使用properties來配置 -->
    <property name="driverclassname">
      <value>${jdbc_driverclassname}</value>
    </property>
    <property name="url">
      <value>${jdbc_url}</value>
    </property>
    <property name="username">
      <value>${jdbc_username}</value>
    </property>
    <property name="password">
      <value>${jdbc_password}</value>
    </property>
  </bean>
 
  <bean id="apptransactionmanager" class="org.springframework.jdbc.datasource.datasourcetransactionmanager">
   <property name="datasource" ref="datasource" />
  </bean>
 
  <tx:annotation-driven proxy-target-class="false" transaction-manager="apptransactionmanager" />
  <!-- 自動掃描了所有的xxxxmapper.xml對應的mapper接口文件,這樣就不用一個一個手動配置mpper的映射了,只要mapper接口類和mapper映射文件對應起來就可以了。 -->
  <bean class="org.mybatis.spring.mapper.mapperscannerconfigurer">
    <property name="basepackage"
      value="com.luo.dao" />
  </bean>
 
  <!-- 配置mybatis的文件 ,mapperlocations配置**mapper.xml文件位置,configlocation配置mybatis-config文件位置-->
  <bean id="sqlsessionfactory" class="org.mybatis.spring.sqlsessionfactorybean">
    <property name="datasource" ref="datasource" />
    <property name="mapperlocations" value="classpath:mapper/*.xml"/>
    <property name="configlocation" value="classpath:mybatis/mybatis-config.xml" />
    <!-- <property name="typealiasespackage" value="com.tiantian.ckeditor.model"
      /> -->
  </bean>
 
  <!-- 自動掃描注解的bean -->
  <context:component-scan base-package="com.luo.service" />
</beans>

3.2、使用@transactional,在添加用戶實現類方法加上注解

?
1
2
3
4
5
6
7
8
@transactional(propagation=propagation.required)
public void adduser(user user) {
  userdao.adduser(user);
  string string = null;
  if(string.equals("")) {
    int i = 0;
  }
}

上面的方法我故意讓其出現空指針異常,會事物回滾

3.3、運行單元測試類

?
1
2
3
4
5
6
7
@test
public void addusertest(){
  user user = new user();
  user.setusername("luoguohui1");
  user.setuserpassword("luoguohui1");
  userservice.adduser(user);
}

發現無法插入進去,但是如果把@transactional去掉,即代碼如下,雖然出現異常,但是數據庫中還是有添加對應數據的:

淺談Spring中@Transactional事務回滾及示例(附源碼)

3.4、源碼下載

本文最終源碼下載:first_maven_project.rar

四、spring中的@transactional必須要了解的概念

spring中的@transactional基于動態代理的機制,提供了一種透明的事務管理機制,方便快捷解決在開發中碰到的問題。

一般使用是通過如下代碼對方法或接口或類注釋:

?
1
@transactional(propagation=propagation.not_supported)

propagation支持7種不同的傳播機制:

required:如果存在一個事務,則支持當前事務。如果沒有事務則開啟一個新的事務。

supports: 如果存在一個事務,支持當前事務。如果沒有事務,則非事務的執行。但是對于事務同步的事務管理器,propagation_supports與不使用事務有少許不同。

not_supported:總是非事務地執行,并掛起任何存在的事務。

requiresnew:總是開啟一個新的事務。如果一個事務已經存在,則將這個存在的事務掛起。

mandatory:如果已經存在一個事務,支持當前事務。如果沒有一個活動的事務,則拋出異常。

never:總是非事務地執行,如果存在一個活動事務,則拋出異常

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

下面是一些需要注意的事項,必須必須必須要看,不然遇到各種坑別說博主沒有提醒你哦:

下面是一些需要注意的事項,必須必須必須要看,不然遇到各種坑別說博主沒有提醒你哦:

下面是一些需要注意的事項,必須必須必須要看,不然遇到各種坑別說博主沒有提醒你哦:

在需要事務管理的地方加@transactional 注解。@transactional 注解可以被應用于接口定義和接口方法、類定義和類的 public 方法上。

@transactional 注解只能應用到 public 可見度的方法上。 如果你在 protected、private 或者 package-visible 的方法上使用 @transactional 注解,它也不會報錯, 但是這個被注解的方法將不會展示已配置的事務設置。

注意僅僅 @transactional 注解的出現不足于開啟事務行為,它僅僅 是一種元數據。必須在配置文件中使用配置元素,才真正開啟了事務行為。

通過 元素的 “proxy-target-class” 屬性值來控制是基于接口的還是基于類的代理被創建。如果 “proxy-target-class” 屬值被設置為 “true”,那么基于類的代理將起作用(這時需要cglib庫cglib.jar在classpath中)。如果 “proxy-target-class” 屬值被設置為 “false” 或者這個屬性被省略,那么標準的jdk基于接口的代理將起作用。

spring團隊建議在具體的類(或類的方法)上使用 @transactional 注解,而不要使用在類所要實現的任何接口上。在接口上使用 @transactional 注解,只能當你設置了基于接口的代理時它才生效。因為注解是 不能繼承 的,這就意味著如果正在使用基于類的代理時,那么事務的設置將不能被基于類的代理所識別,而且對象也將不會被事務代理所包裝。

@transactional 的事務開啟 ,或者是基于接口的 或者是基于類的代理被創建。所以在同一個類中一個方法調用另一個方法有事務的方法,事務是不會起作用的。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://blog.csdn.net/u013142781/article/details/50421904

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本中文高清 | 蜜桃欧美性大片免费视频 | 欧美 日韩 中文 | 中文字幕一区2区 | 调教小男生抽打尿孔嗯啊视频 | 久草干 | 国产精品视频成人 | 国产做爰全免费的视频黑人 | 日日草天天干 | 国产精品无码久久久久 | 国产在线观看一区二区三区 | 春光影院理论片 | 久草在线视频看看 | 中文字幕在线资源 | 久久精品亚洲精品国产欧美kt∨ | 亚洲人成网站在e线播放 | 国产视频在线观看免费 | 欧美日韩视频网站 | 久久精品久久精品国产大片 | 日本特级a一片免费观看 | 午夜人体| 一级毛片播放 | 亚洲午夜精品视频 | 男女一边摸一边做羞羞视频免费 | 91热久久免费频精品黑人99 | 日韩a毛片免费观看 | 日韩视频一二三 | 久久综合精品视频 | 久久久精品网 | 亚洲电影免费观看国语版 | 色综合777| 亚洲一区二区在线免费 | 欧产日产国产精品乱噜噜 | 日韩视频一 | 精品久久久久久久久久久下田 | 国产精品自在线拍 | 免费国产 | 黄色免费电影网址 | 国产一区二区不卡视频 | 久草视频免费 | 免费嗨片首页中文字幕 |