javascript
Spring 事情具体详尽的解释
1、 Spring事務管理機制 三個核心部分?
1) PlatformTransactionManager ?平臺的事務管理器 ?commit 提交事務、rollback 回滾事務 、 TransactionStatus getTransaction(TransactionDefinition definition)?
2) TransactionDefinition ?事務定義信息(和事務管理相關一些參數) ?隔離級別、傳播級別、超時 、事務是否僅僅讀 ?(靜態信息)?
3) TransactionStatus 事務狀態 ?(事務執行過程中 一些動態信息 )?
關系: 事務管理參數信息由 TransactionDefinition 載入, Spring事務管理由PlatformTransactionManager ?完畢, PlatformTransactionManager 管理事務過程中依據 TransactionDefinition 定義事務管理信息來管理事務 ?。在事務執行過程中不同一時候刻 事務狀態信息不同, TransactionStatus 就表示不同一時候刻事務狀態信息?
第一個組件 事務管理器 PlatformTransactionManager ?接口?
org.springframework.jdbc.datasource.DataSourceTransactionManager ------- 針對jdbc開發或者 iBatis開發 進行事務管理?
org.springframework.orm.hibernate3.HibernateTransactionManager ?------- ?針對Hibernate3開發 進行事務管理?
第二個組件 事務定義信息 TransactionDefinition?
隔離級別:?
1) read_uncommitted 讀未提交 ? 引發全部事務隔離問題(臟讀、不可反復讀、虛讀)
2) read_committed 讀已提交 ?不會發生臟讀,會導致不可反復讀和虛讀?
3) repeatable_read 反復讀 ?不會發生 臟讀和不可反復讀。會導致虛讀?
4) serializable ?序列化 採用串行方式管理事務,同一時間,僅僅能有一個事務在操作 ,阻止全部隔離問題發生?
DEFAULT 採取數據庫默認隔離級別 ?Oracle read_committed、 Mysql repeatable_read?
事務傳播行為:(七種)
1) PROPAGATION_REQUIRED : 支持當前事務。假設不存在 就新建一個 ?, 將 deleteUser 和 removeAllOrders 放入同一個事務 ?(Spring默認提供事務傳播級別)
2) PROPAGATION_SUPPORTS : 支持當前事務。假設不存在。就不使用事務 ?
3) PROPAGATION_MANDATORY : 支持當前事務,假設不存在,拋出異常?
4) PROPAGATION_REQUIRES_NEW : 假設有事務存在。掛起當前事務,創建一個新的事務 ?, deleteUser和removeAllOrder 兩個事務運行。無不論什么關系?
5) PROPAGATION_NOT_SUPPORTED : 以非事務方式執行。假設有事務存在,掛起當前事務
6) PROPAGATION_NEVER ?: ?以非事務方式執行,假設有事務存在,拋出異常
7) PROPAGATION_NESTED : 假設當前事務存在,則嵌套事務運行
事物傳播行為的須要性:
二、 Spring事務管理案例 ?轉賬案例(轉出金額和轉入金額)
Spring事務管理 分為編程式事務管理和 聲明式事務管理?
編程式事務管理:在程序中通過編碼來管理事務。事務代碼侵入,開發中極少應用
聲明式事務管理:無需侵入事務管理代碼,開發維護及其方便,底層應用Spring AOP來完畢?
1、編程式 完畢事務管理
CREATE TABLE `account` (
? `id` int(11) NOT NULL AUTO_INCREMENT,
? `name` varchar(20) NOT NULL,
? `money` double DEFAULT NULL,
? PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
INSERT INTO `account` VALUES ('1', 'aaa', '1000');
INSERT INTO `account` VALUES ('2', 'bbb', '1000');
導入jar包 spring基本6個 aop4個 jdbc2個 c3p01個 驅動1個?
導入jdbc.properties和log4j.properties
jdbc.driverClass= com.mysql.jdbc.Driver jdbc.url=jdbc:mysql:///springtx jdbc.user= root jdbc.password=abc### direct log messages to stdout ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.err log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n### direct messages to file mylog.log ### log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File=c:/mylog.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n### set log levels - for more verbose logging change 'info' to 'debug' ###log4j.rootLogger=info, stdout業務層 IAccountServive ?AccountServiceImpl? package service;/*** 以字母I開始 通常表示一個接口* @author **/ public interface IAccountService {/*** 轉賬操作* @param outAccount 轉出賬戶* @param inAccount 轉入賬戶* @param money 轉賬金額 */public void transfer(String outAccount, String inAccount , double money); } package service;import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate;import dao.IAccountDAO; /*** 編程式事務管理* @author **/ public class AccountServiceImpl implements IAccountService {private IAccountDAO accountDAO;// 事務模板。編程式事務。是通過該模板進行管理private TransactionTemplate transactionTemplate;@Overridepublic void transfer(final String outAccount, final String inAccount, final double money) {transactionTemplate.execute(new TransactionCallbackWithoutResult() {@Overrideprotected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {// 轉賬 分為轉入和轉出accountDAO.out(outAccount, money); // int d= 1/0;accountDAO.in(inAccount, money);System.out.println("轉賬成功!
"); } }); } public void setAccountDAO(IAccountDAO accountDAO) { this.accountDAO = accountDAO; } public void setTransactionTemplate(TransactionTemplate transactionTemplate) { this.transactionTemplate = transactionTemplate; } }
DAO層 IAccountDAO ?AccountDAOImpl
package dao;/*** Account 操作* @author **/ public interface IAccountDAO {// 轉出public void out(String outAccount, double money);// 轉入public void in(String inAccount, double money); } package dao;import java.sql.ResultSet; import java.sql.SQLException;import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.support.JdbcDaoSupport;import domain.Account;public class AccountDAOImpl extends JdbcDaoSupport implements IAccountDAO {@Overridepublic void out(String outAccount, double money) {// 推斷金額是否滿足Account account = this.getJdbcTemplate().queryForObject("select * from account where name = ?
" , new RowMapper<Account>(){ @Override public Account mapRow(ResultSet rs, int rowNum) throws SQLException { Account account = new Account(); account.setId(rs.getInt("id")); account.setName(rs.getString("name")); account.setMoney(rs.getDouble("money")); return account; } },outAccount); if(account.getMoney() < money){ // 轉賬金額大于余額 throw new RuntimeException("余額不足無法轉賬!"); } // 轉賬 this.getJdbcTemplate().update("update account set money=money-? where name=?
", money ,outAccount); } @Override public void in(String inAccount, double money) { // 轉入 this.getJdbcTemplate().update("update account set money=money + ? where name=?
", money ,inAccount); } }
在業務層中事務 TransactionTemplate 模板工具類。進行事務管理?* 將TransactionTemplate對象注入到Service中?
* 將相應事務管理器 注入個 TransactionTemplate ?
applicationContext.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: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"> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- 配置數據源 --> <!-- c3p0數據源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="jdbcUrl" value="${jdbc.url}"></property> <property name="user" value="${jdbc.user}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <!-- 配置JdbcTemplate , 將數據源注入到jdbcTemplate --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 將jdbcTemplate 注入DAO --> <bean id="accountDAO" class="dao.AccountDAOImpl"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> <!-- 編程式事務管理 --> <!-- 1、配置事務管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 2、將事務管理器 注入給 事務模板 --> <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="transactionManager"></property> </bean> <!-- 3、將模板 給Service --> <!-- 將DAO注入Service --> <bean id="accountService" class="service.AccountServiceImpl"> <property name="accountDAO" ref="accountDAO"></property> <property name="transactionTemplate" ref="transactionTemplate"></property> </bean> </beans>
2、 聲明式事務管理 (原始方式)TransactionProxyFactoryBean ?事務代理工廠Bean為目標類生成代理。進行事務管理?
上面的其它部分不變。僅僅須要修改AccountServiceImpl,創建新的AccountServiceImpl2
package service;import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional;import dao.IAccountDAO;/*** 聲明式事務管理* * @author seawind* */ @Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT,readOnly=false,rollbackFor=ArithmeticException.class) // 進行事務管理 public class AccountServiceImpl2 implements IAccountService {private IAccountDAO accountDAO;@Overridepublic void transfer(final String outAccount, final String inAccount,final double money) {// 轉賬 分為轉入和轉出accountDAO.out(outAccount, money);//int d= 1/0;accountDAO.in(inAccount, money);System.out.println("轉賬成功!");}public void setAccountDAO(IAccountDAO accountDAO) {this.accountDAO = accountDAO;}} applicationContext2.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: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"> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- 配置數據源 --> <!-- c3p0數據源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="jdbcUrl" value="${jdbc.url}"></property> <property name="user" value="${jdbc.user}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <!-- 配置JdbcTemplate , 將數據源注入到jdbcTemplate --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 將jdbcTemplate 注入DAO --> <bean id="accountDAO" class="dao.AccountDAOImpl"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> <!-- 將DAO注入Service --> <bean id="accountService" class="service.AccountServiceImpl2"> <property name="accountDAO" ref="accountDAO"></property> </bean> <!-- 事務管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 為accountService 生成代理對象,進行事務管理 --> <bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <!-- 須要事務管理器 --> <property name="transactionManager" ref="transactionManager"></property> <!-- 被代理目標對象 --> <property name="target" ref="accountService"></property> <!-- 對目標業務接口生成代理 --> <property name="proxyInterfaces" value="service.IAccountService"></property> <!-- 事務定義參數 --> <property name="transactionAttributes"> <!-- 為事務管理方法 配置 隔離級別、傳播級別、僅僅讀 --> <props> <!-- 代理方法名 --> <prop key="*">PROPAGATION_REQUIRED,+java.lang.ArithmeticException</prop> </props> </property> </bean> </beans>
transactionAttributes 事務屬性配置格式?prop格式:PROPAGATION,ISOLATION,readOnly,-Exception,+Exception
1) PROPAGATION 傳播行為
2) ISOLATION 隔離級別?
3) readOnly : 僅僅讀事務。不能進行改動操作
4) -Exception : 發生這些異常回滾事務?
5) +Exception : 發生這些異常仍然提交事務?
<prop key="*">PROPAGATION_REQUIRED,+java.lang.ArithmeticException</prop> ?發生java.lang.ArithmeticException 事務也會提交
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop> 事務是僅僅讀,不能進行改動操作 ?
3、 聲明式事務管理 (使用XML配置聲明式事務 基于tx/aop)
導入tx 和 aop schema 名稱空間?
applicationContext3.xml
> <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.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:property-placeholder location="classpath:jdbc.properties"/> <!-- 配置數據源 --> <!-- c3p0數據源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="jdbcUrl" value="${jdbc.url}"></property> <property name="user" value="${jdbc.user}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <!-- 配置JdbcTemplate , 將數據源注入到jdbcTemplate --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 將jdbcTemplate 注入DAO --> <bean id="accountDAO" class="dao.AccountDAOImpl"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> <!-- 將DAO注入Service --> <bean id="accountService" class="service.AccountServiceImpl2"> <property name="accountDAO" ref="accountDAO"></property> </bean> <!-- 事務管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 通過tx:advice 配置事務管理增強 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- 配置事務屬性 --> <tx:attributes> <!-- 對哪個方法用事務管理 --> <tx:method name="transfer" propagation="REQUIRED" isolation="DEFAULT" read-only="false" /> </tx:attributes> </tx:advice> <!-- 配置aop --> <aop:config proxy-target-class="false"> <!-- 配置切點 --> <aop:pointcut expression="execution(* service.AccountServiceImpl2.*(..))" id="mytransactionpointcut"/> <!-- 將一個Advice作為 一個切面 Advisor --> <!-- 對 mytransactionpointcut 切點 進行 txAdvice 增強 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="mytransactionpointcut"/> </aop:config> </beans>
4、聲明式事務管理 (使用注解配置 )
對須要管理事務的方法,加入注解@Transactionnal?
* @Transactionnal 能夠載入類上面 或者 方法名上面?
在applicationContext.xml中加入 <tx:annotation-driven transaction-manager="transactionManager"/>?
@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT,readOnly=false,rollbackFor=ArithmeticException.class)
propagation=Propagation.REQUIRED 傳播行為
isolation=Isolation.DEFAULT 隔離級別
readOnly=false 是否僅僅讀
rollbackFor=ArithmeticException.class 發生異常回滾?
noRollbackFor=xxx.class 發生異常 仍然提交事務?
applicationContext4.xml
版權聲明:本文博主原創文章。博客,未經同意不得轉載。
轉載于:https://www.cnblogs.com/blfshiye/p/4872944.html
總結
以上是生活随笔為你收集整理的Spring 事情具体详尽的解释的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FineReport——JS二次开发(局
- 下一篇: 【软件工程导论题型大总结】名词解释总结