日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

【SSM框架系列】Spring - JdbcTemplate声明式事务

發布時間:2025/5/22 javascript 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【SSM框架系列】Spring - JdbcTemplate声明式事务 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JdbcTemplate概述

  • 以往使用jdbc時,每次都需要自己獲取PreparedStatement,執行sql語句,關閉連接等操作。操作麻煩冗余,影響編碼的效率。

  • Spring把對數據庫的操作在jdbc上面做了深層次的封裝,使用spring的注入功能,可以把DataSource注冊到JdbcTemplate(jdbc模板)之中,這樣我們只需要做一些簡單的操作(eg:編寫SQL語句、傳遞參數)就可以了。

  • spring框架根據不同持久層方案為我們提供了不同的JdbcTemplate(jdbc模板類)。例如:操作關系型數據的JdbcTemplate和HibernateTemplate,操作nosql數據庫的RedisTemplate,操作消息隊列的JmsTemplate等等

QuickStart

導入spring-jdbc和spring-tx坐標

<dependencies><!-- Spring上下文坐標,如果使用到了Spring的上下文容器,需要導入--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.5.RELEASE</version></dependency><!-- 使用Spring JdbcTemplate需要導入下面兩個坐標 --><!-- 導入spring-jdbc坐標 --><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.0.5.RELEASE</version></dependency><!-- 導入spring-tx事務管理坐標,如果不使用事務管理,可以不導 --><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>5.0.5.RELEASE</version></dependency><!-- 因為操作Mysql數據庫,需要導入數據庫驅動坐標 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.6</version></dependency><!-- 數據源選擇使用c3p0連接池 --><dependency><groupId>c3p0</groupId><artifactId>c3p0</artifactId><version>0.9.1.2</version></dependency><!-- 使用單元測試 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency> </dependencies>

在測試類中創建JdbcTemplate對象并使用

public class AccountTest {@Testpublic void test1() throws PropertyVetoException {//1. 創建JdbcTemplate模板對象JdbcTemplate jdbcTemplate = new JdbcTemplate();//2. 設置數據源ComboPooledDataSource對象//創建DataSource對象,并設置連接四要素ComboPooledDataSource dataSource = new ComboPooledDataSource();dataSource.setDriverClass("com.mysql.jdbc.Driver");dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");dataSource.setUser("root");dataSource.setPassword("root");//JdbcTemplate依賴于DataSourcejdbcTemplate.setDataSource(dataSource);//3. 執行增刪改查操作int row = jdbcTemplate.update("insert into account values (?,?)", "趙麗穎", 666);System.out.println(row);} }

Spring容器創建并維護JdbcTemplate及相關對象

1)思路分析

  • Spring的核心之一就是Ioc,控制反轉,也就是由Spring容器負責對象的創建和對象間依賴關系的管理。上述代碼中DataSource、JdbcTemplate對象以及他們之間的關系都是由我們手動創建,并且手動設置依賴關系的。

  • 經過觀察,JdbcTemplate類可以通過無參構造創建該類對象,同時又setDataSource()方法用于設置數據源依賴,所以JdbcTemplate類的對象完全可以交給Spring容器管理,數據源DataSource可以交給Spring容器管理,那我們就可以使用Spring容器管理并維護上述兩個對象。

2)代碼實現

導入坐標:因為要使用到Spring容器創建對象并維護對象依賴關系,所以要在pom.xml中確定導入了spring-context坐標。

<!-- Spring上下文坐標,使用到了Spring的上下文容器,需要 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.5.RELEASE</version></dependency>

Xml配置:在applicationContext.xml文件中先配置數據源,然后配置JdbcTemplate,最后將數據源注入到JdbcTemplate中。

<!-- DataSource對象 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"></property><property name="jdbcUrl" value="jdbc:mysql:///test"></property><property name="user" value="root"></property><property name="password" value="root"></property> </bean><!-- JdbcTemplate對象 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"></property> </bean>

Java代碼:通過Spring容器獲得JdbcTemplate對象,調用JdbcTemplate對象的update方法,傳入sql語句及參數完成插入數據的操作

@Test public void test2() throws PropertyVetoException {//1. 獲取JdbcTemplate模板對象(Spring已經將DataSource注入其中)ApplicationContext ac= new ClassPathXmlApplicationContext("applicationContext.xml");JdbcTemplate jdbcTemplate = ac.getBean(JdbcTemplate.class);//2. 不需要設置數據源ComboPooledDataSource對象//3. 執行增刪改查操作int row = jdbcTemplate.update("insert into account values (?,?)", "shheima", 60000);System.out.println(row); }

抽取jdbc配置

  • 目前的jdbc四要素已經脫離了代碼,已經實現了解耦,之后如果數據庫信息修改后直接修改配置文件即可。

  • 但是目前數據庫四要素的配置耦合進了Spring的配置文件,為了更方便的維護,建議將該信息抽取到一個獨立properties文件中。

  • 提取數據源的基本連接信息到配置文件jdbc.properties(名字任意,格式為properties)

jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql:///test jdbc.username=root jdbc.password=root

引入properties文件,并修改DataSource注入基本參數的配置,具體如下:

<!-- 導入jdbc.properties文件。classpath表示文件在類路徑下 --> <context:property-placeholder location="classpath:jdbc.properties"/><!-- DataSource對象 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><!--property的name屬性名稱通過set方法截取;因為屬性值為String,所以通過value屬性設置通過${key}的方式可以從properties文件中讀取key對應的值。--><property name="driverClass" value="${jdbc.driver}"></property><property name="jdbcUrl" value="${jdbc.url}"></property><property name="user" value="${jdbc.username}"></property><property name="password" value="${jdbc.password}"></property> </bean><!-- JdbcTemplate對象 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"></property> </bean>

如果有多個properties文件需要引入可以使用通配符:

<!--如果需要導入多個文件,可以使用通配符 --> <context:property-placeholder location="classpath:*.properties"/>

JdbcTemplate常用操作

jdbcTemplate更新數據庫常用方法

  • update (更新數據,也就是增刪改)
  • queryForObject (單行查詢)
  • query (多行查詢)
  • queryForObject (單值查詢)

JdbcTemplate常用操作-增刪改操作

JdbcTemplate對象的update方法可以完成增刪改的操作,只是傳入的sql語句及對應參數不同。

語法:對數據庫進行增刪改的操作,返回影響的行數 jdbcTemplate.update(sql語句, sql語句參數列表)

代碼如下:

@RunWith(SpringJUnit4ClassRunner.class) //指定測試器 @ContextConfiguration("classpath:applicationContext.xml") //指定Spring配置文件并加載 public class JdbcTemplatetTest {@Autowired //自動注入JdbcTemplate對象private JdbcTemplate jdbcTemplate;/*** testUpdate:測試刪除*/@Testpublic void testDelete(){int row = jdbcTemplate.update("delete from account where name=?","nanjingheima");System.out.println(row);}/*** testUpdate:測試修改*/@Testpublic void testUpdate(){int row = jdbcTemplate.update("update account set money=? where name=?", 500000,"hzheima");System.out.println(row);} }

JdbcTemplate常用操作-查詢操作

JdbcTemplate對象的query**()方法可以完成查詢的操作。

多行查詢 List<T> query(sql語句, new BeanPropertyRowMapper<T>(T.class)) 查詢并將結果通過BeanPropertyRowMapper將查詢的結果集封裝到List集合中 List<T> query(sql語句, new BeanPropertyRowMapper<T>(T.class), sql語句參數列表)查詢并將結果通過BeanPropertyRowMapper將查詢的結果集封裝到List集合中 單行查詢 T queryForObject(sql語句, new BeanPropertyRowMapper<T>(T.class), sql語句參數列表)單行查詢查詢并將結果通過BeanPropertyRowMapper將查詢結果封裝到javaBean對象中 單值查詢 要求的查詢結果類型 queryForObject(sql語句, 要求的查詢結果類型.class)查詢并將結果通過BeanPropertyRowMapper將聚合查詢結果轉化到要去的結果類型 要求的查詢結果類型 queryForObject(sql語句, 要求的查詢結果類型.class, sql語句參數列表)查詢并將結果通過BeanPropertyRowMapper將聚合查詢結果轉化到要去的結果類型

代碼如下:

@RunWith(SpringJUnit4ClassRunner.class) //指定測試器 @ContextConfiguration("classpath:applicationContext.xml") //指定Spring配置文件并加載接卸 public class JdbcTemplatetTest {@Autowired //自動注入JdbcTemplate對象private JdbcTemplate jdbcTemplate;/*** testQueryCount:聚合查詢*/@Testpublic void testQueryCount(){long count = jdbcTemplate.queryForObject("select count(*) from " +"account",long.class);System.out.println(count);count = jdbcTemplate.queryForObject("select count(*) from " +"account where money = ?",long.class,60000);System.out.println(count);}/*** testQueryOne:查詢單個*/@Testpublic void testQueryOne(){Account account = jdbcTemplate.queryForObject("select * from account " +"where name = ?",new BeanPropertyRowMapper<Account>(Account.class) ,"hzheima");System.out.println(account);}/*** testQuerySome:按條件查詢部分*/@Testpublic void testQuerySome(){List<Account> accounts = jdbcTemplate.query("select * from account where money = ?",new BeanPropertyRowMapper<Account>(Account.class), 60000);System.out.println(accounts);}/*** testQueryAll:查詢所有*/@Testpublic void testQueryAll(){List<Account> accounts = jdbcTemplate.query("select * from account",new BeanPropertyRowMapper<Account>(Account.class));System.out.println(accounts);} }

補充:

批量更新(增刪改)

//批量增刪改,batchArgs為批量更新的參數列表,類型為Object[]數組類型的List集合 jdbcTemplate.batchUpdate(String sql, List batchArgs); /***testBatechUpdate:批量更新,批量 insert,update,delete*/ @Test public void testBatechUpdate() {String sql = "insert into account(name, money) values(?,?)";List<Object[]> batchArgs = new ArrayList<Object[]>();batchArgs.add(new Object[] {"zhangsan",2000});batchArgs.add(new Object[] {"lisi",2000});batchArgs.add(new Object[] {"wangwu",2000});jdbcTemplate.batchUpdate(sql, batchArgs); }

自定義綁定(使用場景較少)

除了使用系統提供的RowMapper的實現類之外,我們也可以自己手動編寫RowMapper實現類,以實現特殊的結果集到javaBean的封裝轉化,實例代碼如下:

Account account = jdbcTemplate.queryForObject("select * from account where money = ?",new Object[]{60000L},new RowMapper<Account>() {//重寫該方法時只需要將獲取的結果集中單個結果封裝到某個JavaBean中,//query方法會根據實際情況選擇選擇返回一個javaBan對象還是一個Listpublic Account mapRow(ResultSet rs, int rowNum) throws SQLException {Account account = new Account();account.setUsername(rs.getString("name"));account.setMoney(rs.getString("money"));return account;}});

執行DDL語句(使用場景很少)

Spring的JdbcTemplate也可以使用execute(…)方法運行任意SQL語句。所以,該方法通常用于DDL語句。下面代碼創建一個表:

jdbcTemplate.execute("create table mytable (id integer, name varchar(100))");

Spring事務管理

Spring事務管理主要應用在軟件分層之后的業務層,也就是Service層。一個service層的操作依賴的多個dao層操作要被事務管理起來,保證數據安全準確。eg:轉賬。

Spring事務管理核心API

Spring事務管理的三個高層接口

  • PlatformTransactionManager:Spring提供的事務管理器核心接口,內部規定了常用的事務管理的規則。

  • TransactionDefinition:Spring提供的封裝事務屬性的接口,用于封裝和操作事務的屬性

  • TransactionStatus:Spring提供的封裝事務狀態的接口,用于封裝事務的狀態

PlatformTransactionManager

Spring提供的事務管理器接口,整個Spring進行事務管理的核心接口,內部規定了常用的操作事務的規則。

a) 接口中規定的操作事務的方法:

操作事務的方法
TransactionStatus getTransaction
(TransactionDefination defination)
根據事務定義信息獲取事務狀態信息
void commit(TransactionStatus status)提交事務
void rollback(TransactionStatus status)回滾事務

根據上述方法,

? TransactionStatus getTransaction(TransactionDefination defination)

我們可以推斷:PlatformTransactionManager根據TransactionDefinition對象獲得 TransactionStatus 對象

  • 三者的關系平臺事務管理器(PlatformTransactionManager)根據 事務屬性管理器(TransactionDefinition)中定義的事務屬性對事務進行管理;事務運行過程中,每一個時間點都有對應的事務狀態信息(TransactionStatus)。

  • 也就是說,干活的是Manager(PlatformTransactionManager),根據事務屬性管理器(TransactionDefinition)的配置信息干活,在干活的過程中會有一些狀態信息,通過TransactionStatus體現。

b) 不同的Dao層技術則有不同的實現類

PlatformTransactionManager是一個接口,只負責制定規范,那具體的實現是哪些類呢?Spring根據不同的數據持久層技術提供了不同實現類:

  • Dao 層技術是jdbc、 mybatis、Apache DBUtils時:org.springframework.jdbc.datasource.DataSourceTransactionManager

  • Dao層技術是hibernate時:org.springframework.orm.hibernate5.HibernateTransactionManager

TransactionDefinition

Spring提供的封裝事務屬性的接口,用于規定封裝事務的屬性,通過該接口實現類對象可以獲取(子類對象可以設置)事務屬性。

a) 接口中規定的獲取事務屬性的方法:

方法名說明
int getIsolationLevel()獲取事務的隔離級別,隔離級別用于解決事務并發訪問讀問題
int getPropagationBehavior()獲取事務的傳播行為,解決的就是兩個事務方法事務統一性的問題
int getTimeout()獲取超時時間
boolean isReadOnly()判斷當前事務是否只讀
  • 接口中只規定了獲取的方法,在其實現類中有設置的方法,eg:DefaultTransactionDefinition

  • 事務屬性需要在進行聲明式事務配置時,需要在配置文件中對于事務屬性進行配置,以便Spring框架進行解析。

b) 事務的四個特性:

ACID:原子性、一致性、隔離性、持久性。

  • Atomic(原子性):事務中包含的操作被看做一個邏輯單元,這個邏輯單元中的操作要么全部成 功,要么全部失敗。

  • Consistency(一致性):事務完成時,數據必須處于一致狀態,數據的完整性約束沒有被破壞,事務在執行過程中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。

  • Isolation(隔離性):事務允許多個用戶對同一個數據進行并發訪問,而不破壞數據的正確性 和完整性。同時,并行事務的修改必須與其他并行事務的修改相互獨立。

  • Durability(持久性):事務結束后,事務處理的結果必須能夠得到持久化。

c) 事務屬性:隔離級別(理解)

在并發訪問的時候,會出現一些讀問題。

讀問題

  • 臟讀:一個事務讀取了另外一個事務改寫但還未提交的更新數據,如果這些數據被回滾,則讀到的數據是無效的。
    • eg:小明工資表,老板算工資的時候被小明看到了。
  • 不可重復讀:在同一個事務中,多次讀取同一個數據返回的結果有所不同。換句話說就是,后續讀取可以讀取到另一個事務已提交的更新數據。相反,“可重復讀”在同一個事務中多次讀取數據時,能保證數據時一樣,也就是,后續讀取不能讀取到另一個事務已經提交的更新數據。
    • eg:小明買手機前后老婆查賬。
  • 幻讀:一個事務讀取了(按照某個規則的)全部數據后,另一個事務插入了一些記錄,當后續再次查詢的時候,幻讀就發生了。在后續查詢中,第一個事務就會發現有一些原來沒有的記錄。
    • eg:老婆查崗打印流水,又發現消費多了。

設置隔離級別,可以解決事務并發產生的讀問題,如臟讀、不可重復讀和虛讀(幻讀)。

  • ISOLATION_DEFAULT 默認級別,使用數據庫內部默認級別(mysql - Repeatable read,其他大多數是 - Read committed)

  • ISOLATION_READ_UNCOMMITTED 讀未提交:一個事務可以讀取另一個未提交事務的數據,該級別下容易上述所讀有問題。性能最高,安全性最差。

  • ISOLATION_READ_COMMITTED 讀提交:一個事務要等另一個事務提交后才能讀取數據。能解決臟讀問題,但是可能會有不可重復讀、幻讀的問題。

  • ISOLATION_REPEATABLE_READ 重復讀,在開始讀取數據(事務開啟)時,不再允許修改操作。能解決臟讀、不可重復讀的問題,但是可能會有幻讀的問題。

  • ISOLATION_SERIALIZABLE 序列化,解決所有三個問題,相當于鎖表安全性高,串行化處理事務,但是非常耗數據庫性能,效率低下,一般不用。

列表如下(√表示可能出現,×表示不會出現):

隔離級別\讀問題臟讀不可重復讀幻讀
Read uncommitted讀未提交
Read commited讀提交×
Repeatable read重復讀××
Serializable×××

上述事務的四大特性、四個隔離級別是原來是在數據庫內部規定的,Spring從數據庫引入了 過來。但是接下來的七種傳播行為和數據庫沒有直接關系,是Spring為了解決實際開發中的問題而引入的。

d) 事務屬性:傳播行為

即然是傳播,那么至少有兩個東西,才可以發生傳播。單體不存在傳播這個行為。

事務傳播行為(propagation behavior)指的就是當一個事務方法A調用另一個事務方法B時,事務方法B應該以何種事務特性進行。是繼續在調用者methodA的事務中運行呢,還是為自己開啟一個新事務運行,這就是由methodB的事務傳播行為決定的。

事務傳播行為是為了解決業務方法相互調用時,事務如何管理的問題。

通常情況下,一個業務方法就是一個事務。但是多個業務方法相互調用的時候可能會出現問題。

eg:取錢打印小票

取錢 required

{

? 插卡 required

? 輸密碼 required

? 吐錢 required

? 打印小票 requires_new

}

七種事務傳播行為(當前方法:被調用的方法):

  • PROPAGATION_REQUIRED:表示當前方法必須運行在事務中。如果調用者事務存在,當前方法就會在該事務中運行;否則,會啟動一個新的事務。一般的選擇(默認值)。

  • PROPAGATION_SUPPORTS:表示當前方法不需要事務上下文,但是如果當前事務存在的話,那么該方法會在這個事務中運行。

  • PROPAGATION_MANDATORY:表示當前方法必須在事務中運行,如果當前事務不存在,則會拋出一個異常。

  • PROPAGATION_REQUERS_NEW:表示當前方法必須運行在它自己的事務中,一個新的事務將被啟動。如果存在當前事務,該方法執行期間,當前事務會被掛起。

  • PROPAGATION_NOT_SUPPORTED:表示當前方法不應該運行在事務中。如果存在當前事務,該方法運行期間,當前事務會被掛起。

  • PROPAGATION_NEVER:表示當前方法不應該運行在事務上下文中。如果存在當前事務,則會拋出異常。

  • PROPAGATION_NESTED:表示如果當前已經存在一個事務,那么該方法將會在嵌套事務中運行。嵌套的事務可以獨立于當前事務進行獨立的提交和回滾。如果當前事務不存在,那么其行為與PROPAGATION_REQUIRED一樣。注意各廠商對這種傳播行為的支持不同,可以參考資源管理器的文檔來確認他們是否支持嵌套事務。

e) 事務其他屬性

超時時間:默認值是-1,沒有超時限制。如果有,以秒為單位進行設置。一般使用默認。
是否只讀:建議查詢操作時設置為只讀,效率更高。

事務中的readOnly屬性表示對應的事務會優化為只讀事務。如果值為true就會告訴Spring我這個方法里面沒有insert或者update,你只需要提供只讀的數據庫Connection就行了,這種執行效率會比read-write的Connection高。

如果設置了只讀事務,Mysql數據庫增刪改會報錯,Oracle無影響(不支持)

TransactionStatus

Spring提供的封裝事務狀態的接口,用于封裝事務的狀態。

事務的狀態是事務自身的屬性,在事務管理不同的時間段,事務會表現出不同的狀態,所以不需要配置。

a) 接口中規定的判斷事務狀態的方法:

方法名說明
boolean isNewTransaction()是否是新事務。如果返回false,說明當前事務已存在,或者該操作沒在事務環境中。
boolean hasSavepoint()是否存在回滾點
boolean isRollbackOnly()判斷當前事務是否被設置了rollback-only
boolean isCompleted()事務是否已結束

聲明式事務概述

  • Spring 的聲明式事務就是采用聲明的方式來設置事務的屬性參數,事務會按照指定的規則自動管理運行。

  • 這里所說的聲明,指在配置文件中配置(或添加注解)<事務的屬性參數>,用在Spring 配置文件(注解)中聲明的事務來代替用代碼編寫的事務。

  • 業務代碼運行過程中,Spring容器(中的事務管理器對象)跟據配置文件中的配置參數,動態的把事務加入到業務代碼中。(AOP思想)

  • (編碼時)事務管理不侵入業務組件。編寫業務代碼的時候并沒有體現事務管理的代碼。

  • 事務管理策略維護方便。如果需要修改事務管理策略,只要在配置文件上修改,無需改變代碼重新編譯。

基于XML的聲明式事務管理

配置切點

<!--pointcut 目標對象 內部的方法就是切點--> <bean id="accountService" class="cs.wy.service.impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"/> </bean>

配置通知(事務管理器)

<!-- advice 配置通知-事務管理器就是通知(增強)所在的類 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="*"/></tx:attributes> </tx:advice><!--jdbc 使用的(平臺)事務管理器是 DataSourceTransactionManager事務管理管理的是Service層,service層需要調用dao層操作數據庫,dao層依賴DataSource管理連接池并連接數據庫所以事務管理器中需要注入DataSource --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property> </bean>

配置織入

<!-- weaving 配置事務的織入。 增強方法 + 目標方法 --> <aop:config><aop:advisor advice-ref="txAdvice"pointcut="execution(* cs.wy.service.impl.*.*(..))"/> </aop:config>

基于XML的聲明式事務管理參數詳解

重點分析如下配置:

<!-- advice 配置通知-事務管理器就是通知(增強)所在的類 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="*"/></tx:attributes> </tx:advice>

其中:

tx:advice advice,增強方法所在的類(transactionManager的class)tx:attributes具體的事務需要配到這個標簽里面tx:method 每一個tx:method代表一個類別事務在這個標簽里面的屬性上會配置某些業務邏輯的方法(目標方法),并同時配置對應的事務管理邏輯。tx:nethod ~ namename屬性,用于配置被切點表達式攔截的所有方法中,哪些業務邏輯方法被當前事務管理。該屬性并非Spring事務本身的屬性,而是為了讓該事務匹配關聯到某些業務邏輯方法。name值可以使用*統配,比方說*代表所有方法,save*代表所有save開頭的方法tx:nethod ~ isolation isolation屬性,配置當前事務的隔離級別;如不設置或設置DEFAULT,使用默認的隔離級別。mysql默認的Repeatable read,其他大多數是Read committed。tx:method ~ propagationpropagation屬性,配置當前事務的傳播行為。不設置則使用默認值REQUIRED。tx:method ~ timeouttimeout屬性,配置當前事務的超時時間,不設置則使用默認值-1,表示不限制。一般不設置。 tx:method ~ readonlyreadonly屬性,值為boolean類型。默認值為false。

關于tx:attributes

a. 如果不配置該標簽,所有切點方法都會單獨開啟屬性為默認值的事務 b. 如果配置該標簽,內部tx:method中name匹配的方法會按照當前配置開啟事務,其他未匹配成功的方法會單獨開啟屬性為默認值的事務 c. 存在多個tx:method標簽時,會按照配置順序挨個匹配,直到匹配成功,未匹配成功開啟默認事務 <tx:attributes> <tx:method name="add*" propagation="REQUIRED"/> <tx:method name="upd*" propagation="REQUIRED"/> <tx:method name="del*" propagation="REQUIRED"/> <tx:method name="*" propagation="SUPPORTS" read-only="true" /> </tx:attributes>

關于切點表達式:多個切點表達式可以進行邏輯運算連接(主要使用或||):

<aop:pointcut id="tranpc" expression="execution(* cs.wy.user.service.*.*(..))|| execution(* cs.wy.goods.service.*.*(..))"/>

關于readonly

對于mysql數據庫:如果是查詢操作,建議設為true,優化查詢性能;其他設為false或者不設置使用默認值。增刪改操作如果設置為true,則會拋出異常。 對于Oracle數據庫:無效果

基于注解的聲明式事務控制

使用基于注解的聲明式事務控制,步驟如下:

1、 在xml中開啟自動代理

<aop:aspectj-autoproxy/>

2、然后在方法或類上配置@Transactional注解

1. 配置在類上表示該類下所有方法均開啟事務 2. 配置在方法上,表示該方法開啟事務
  • 推薦做法:
  • 在類上添加@Transactional統一開啟事務, 如有需要,可以在特定方法上添加@Transactional用于配置特屬性。 @Transactional(readOnly = true,,propagation = Propagation.SUPPORTS)

    總結

    以上是生活随笔為你收集整理的【SSM框架系列】Spring - JdbcTemplate声明式事务的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 欧美日韩另类视频 | 中国一级特黄录像播放 | 黑人添美女bbb添高潮了 | 国产女人与zoxxxx另类 | 亚洲国产av一区 | www成人免费视频 | 91视频一区二区 | 久久高清无码电影 | 中国黄色一级视频 | 9久久精品 | 久久青青草原亚洲av无码麻豆 | 锕锕锕锕锕锕锕锕 | 丰满少妇av | 爱爱视频一区 | 毛片a | 美女精品在线 | 日日日干| 国产精品一区二区精品 | 一本色道久久综合精品婷婷 | 麻豆av影视 | 中文字幕精品久久 | 中文字幕人妻一区二区三区在线视频 | 欧美国产另类 | 亚洲免费精品视频 | 亚洲综合自拍 | 激情福利视频 | 动漫羞羞| 亚洲av无码乱码国产精品久久 | 欢乐谷在线观看免费播放高清 | 91噜噜噜| 国产传媒av | 亚洲日本视频 | 四虎永久在线精品 | 91超薄肉色丝袜交足高跟凉鞋 | 免费观看日韩av | 日韩精品在线观看一区二区三区 | 久久视频在线播放 | 欧美a级免费 | 久久久国产精品一区二区三区 | 91av视频网 | 伊人成年网 | 亚洲欧美日韩在线一区 | 色欧美综合 | 国产色a| 欧洲亚洲另类 | 国偷自产av一区二区三区 | 黄页网站免费在线观看 | 久久久香蕉网 | sm久久捆绑调教精品一区 | 黑丝美女av | 91精品国产综合久 | 国产毛片自拍 | 视频二区三区 | 熟女精品一区二区三区 | av小说区| 人人爽人人 | 成人免费午夜视频 | 玉女心经是什么意思 | 亚洲精品麻豆 | 国产精品.xx视频.xxtv | 国产成人av一区二区三区不卡 | 国产人妻人伦精品1国产 | 中文字幕第十一页 | 欧美毛片免费看 | 少妇系列在线观看 | 成人在线观看视频网站 | 日本第一页 | 五月天视频网 | 亚洲爽爽 | 成年在线观看视频 | 成人做爰视频www网站小优视频 | 青草综合| 在线国产三级 | 激情久久久久久久 | 亚洲精品久久久蜜桃 | 夜夜爽av福利精品导航 | 亚洲精品系列 | 四虎视频 | 久草这里只有精品 | 一卡二卡国产 | 国产3p在线播放 | 国产一区精品在线观看 | 尤物视频在线观看视频 | av电影在线观看 | 国产一区二区三区成人 | 亚洲精品a级 | 999zyz玖玖资源站永久 | 精品无码免费视频 | a级在线免费观看 | 亚洲精品男女 | 国产精品交换 | 亚洲欧美综合一区二区 | 精品无码av在线 | 一区二区三区四区亚洲 | 色老妹 | 香港黄色网址 | 欧美性猛交aaaa片黑人 | 精品伦精品一区二区三区视频密桃 | 天天操一操|