javascript
Spring 事情具体详尽的解释
1、 Spring事務(wù)管理機(jī)制 三個(gè)核心部分?
1) PlatformTransactionManager ?平臺(tái)的事務(wù)管理器 ?commit 提交事務(wù)、rollback 回滾事務(wù) 、 TransactionStatus getTransaction(TransactionDefinition definition)?
2) TransactionDefinition ?事務(wù)定義信息(和事務(wù)管理相關(guān)一些參數(shù)) ?隔離級(jí)別、傳播級(jí)別、超時(shí) 、事務(wù)是否僅僅讀 ?(靜態(tài)信息)?
3) TransactionStatus 事務(wù)狀態(tài) ?(事務(wù)執(zhí)行過程中 一些動(dòng)態(tài)信息 )?
關(guān)系: 事務(wù)管理參數(shù)信息由 TransactionDefinition 載入, Spring事務(wù)管理由PlatformTransactionManager ?完畢, PlatformTransactionManager 管理事務(wù)過程中依據(jù) TransactionDefinition 定義事務(wù)管理信息來(lái)管理事務(wù) ?。在事務(wù)執(zhí)行過程中不同一時(shí)候刻 事務(wù)狀態(tài)信息不同, TransactionStatus 就表示不同一時(shí)候刻事務(wù)狀態(tài)信息?
第一個(gè)組件 事務(wù)管理器 PlatformTransactionManager ?接口?
org.springframework.jdbc.datasource.DataSourceTransactionManager ------- 針對(duì)jdbc開發(fā)或者 iBatis開發(fā) 進(jìn)行事務(wù)管理?
org.springframework.orm.hibernate3.HibernateTransactionManager ?------- ?針對(duì)Hibernate3開發(fā) 進(jìn)行事務(wù)管理?
第二個(gè)組件 事務(wù)定義信息 TransactionDefinition?
隔離級(jí)別:?
1) read_uncommitted 讀未提交 ? 引發(fā)全部事務(wù)隔離問題(臟讀、不可反復(fù)讀、虛讀)
2) read_committed 讀已提交 ?不會(huì)發(fā)生臟讀,會(huì)導(dǎo)致不可反復(fù)讀和虛讀?
3) repeatable_read 反復(fù)讀 ?不會(huì)發(fā)生 臟讀和不可反復(fù)讀。會(huì)導(dǎo)致虛讀?
4) serializable ?序列化 採(cǎi)用串行方式管理事務(wù),同一時(shí)間,僅僅能有一個(gè)事務(wù)在操作 ,阻止全部隔離問題發(fā)生?
DEFAULT 採(cǎi)取數(shù)據(jù)庫(kù)默認(rèn)隔離級(jí)別 ?Oracle read_committed、 Mysql repeatable_read?
事務(wù)傳播行為:(七種)
1) PROPAGATION_REQUIRED : 支持當(dāng)前事務(wù)。假設(shè)不存在 就新建一個(gè) ?, 將 deleteUser 和 removeAllOrders 放入同一個(gè)事務(wù) ?(Spring默認(rèn)提供事務(wù)傳播級(jí)別)
2) PROPAGATION_SUPPORTS : 支持當(dāng)前事務(wù)。假設(shè)不存在。就不使用事務(wù) ?
3) PROPAGATION_MANDATORY : 支持當(dāng)前事務(wù),假設(shè)不存在,拋出異常?
4) PROPAGATION_REQUIRES_NEW : 假設(shè)有事務(wù)存在。掛起當(dāng)前事務(wù),創(chuàng)建一個(gè)新的事務(wù) ?, deleteUser和removeAllOrder 兩個(gè)事務(wù)運(yùn)行。無(wú)不論什么關(guān)系?
5) PROPAGATION_NOT_SUPPORTED : 以非事務(wù)方式執(zhí)行。假設(shè)有事務(wù)存在,掛起當(dāng)前事務(wù)
6) PROPAGATION_NEVER ?: ?以非事務(wù)方式執(zhí)行,假設(shè)有事務(wù)存在,拋出異常
7) PROPAGATION_NESTED : 假設(shè)當(dāng)前事務(wù)存在,則嵌套事務(wù)運(yùn)行
事物傳播行為的須要性:
二、 Spring事務(wù)管理案例 ?轉(zhuǎn)賬案例(轉(zhuǎn)出金額和轉(zhuǎn)入金額)
Spring事務(wù)管理 分為編程式事務(wù)管理和 聲明式事務(wù)管理?
編程式事務(wù)管理:在程序中通過編碼來(lái)管理事務(wù)。事務(wù)代碼侵入,開發(fā)中極少應(yīng)用
聲明式事務(wù)管理:無(wú)需侵入事務(wù)管理代碼,開發(fā)維護(hù)及其方便,底層應(yīng)用Spring AOP來(lái)完畢?
1、編程式 完畢事務(wù)管理
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');
導(dǎo)入jar包 spring基本6個(gè) aop4個(gè) jdbc2個(gè) c3p01個(gè) 驅(qū)動(dòng)1個(gè)?
導(dǎo)入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業(yè)務(wù)層 IAccountServive ?AccountServiceImpl? package service;/*** 以字母I開始 通常表示一個(gè)接口* @author **/ public interface IAccountService {/*** 轉(zhuǎn)賬操作* @param outAccount 轉(zhuǎn)出賬戶* @param inAccount 轉(zhuǎn)入賬戶* @param money 轉(zhuǎn)賬金額 */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; /*** 編程式事務(wù)管理* @author **/ public class AccountServiceImpl implements IAccountService {private IAccountDAO accountDAO;// 事務(wù)模板。編程式事務(wù)。是通過該模板進(jìn)行管理private TransactionTemplate transactionTemplate;@Overridepublic void transfer(final String outAccount, final String inAccount, final double money) {transactionTemplate.execute(new TransactionCallbackWithoutResult() {@Overrideprotected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {// 轉(zhuǎn)賬 分為轉(zhuǎn)入和轉(zhuǎn)出accountDAO.out(outAccount, money); // int d= 1/0;accountDAO.in(inAccount, money);System.out.println("轉(zhuǎn)賬成功!
"); } }); } 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 {// 轉(zhuǎn)出public void out(String outAccount, double money);// 轉(zhuǎn)入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){ // 轉(zhuǎn)賬金額大于余額 throw new RuntimeException("余額不足無(wú)法轉(zhuǎn)賬!"); } // 轉(zhuǎn)賬 this.getJdbcTemplate().update("update account set money=money-? where name=?
", money ,outAccount); } @Override public void in(String inAccount, double money) { // 轉(zhuǎn)入 this.getJdbcTemplate().update("update account set money=money + ? where name=?
", money ,inAccount); } }
在業(yè)務(wù)層中事務(wù) TransactionTemplate 模板工具類。進(jìn)行事務(wù)管理?* 將TransactionTemplate對(duì)象注入到Service中?
* 將相應(yīng)事務(wù)管理器 注入個(gè) 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"/> <!-- 配置數(shù)據(jù)源 --> <!-- c3p0數(shù)據(jù)源 --> <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 , 將數(shù)據(jù)源注入到j(luò)dbcTemplate --> <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> <!-- 編程式事務(wù)管理 --> <!-- 1、配置事務(wù)管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 2、將事務(wù)管理器 注入給 事務(wù)模板 --> <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、 聲明式事務(wù)管理 (原始方式)TransactionProxyFactoryBean ?事務(wù)代理工廠Bean為目標(biāo)類生成代理。進(jìn)行事務(wù)管理?
上面的其它部分不變。僅僅須要修改AccountServiceImpl,創(chuàng)建新的AccountServiceImpl2
package service;import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional;import dao.IAccountDAO;/*** 聲明式事務(wù)管理* * @author seawind* */ @Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT,readOnly=false,rollbackFor=ArithmeticException.class) // 進(jìn)行事務(wù)管理 public class AccountServiceImpl2 implements IAccountService {private IAccountDAO accountDAO;@Overridepublic void transfer(final String outAccount, final String inAccount,final double money) {// 轉(zhuǎn)賬 分為轉(zhuǎn)入和轉(zhuǎn)出accountDAO.out(outAccount, money);//int d= 1/0;accountDAO.in(inAccount, money);System.out.println("轉(zhuǎn)賬成功!");}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"/> <!-- 配置數(shù)據(jù)源 --> <!-- c3p0數(shù)據(jù)源 --> <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 , 將數(shù)據(jù)源注入到j(luò)dbcTemplate --> <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> <!-- 事務(wù)管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 為accountService 生成代理對(duì)象,進(jìn)行事務(wù)管理 --> <bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <!-- 須要事務(wù)管理器 --> <property name="transactionManager" ref="transactionManager"></property> <!-- 被代理目標(biāo)對(duì)象 --> <property name="target" ref="accountService"></property> <!-- 對(duì)目標(biāo)業(yè)務(wù)接口生成代理 --> <property name="proxyInterfaces" value="service.IAccountService"></property> <!-- 事務(wù)定義參數(shù) --> <property name="transactionAttributes"> <!-- 為事務(wù)管理方法 配置 隔離級(jí)別、傳播級(jí)別、僅僅讀 --> <props> <!-- 代理方法名 --> <prop key="*">PROPAGATION_REQUIRED,+java.lang.ArithmeticException</prop> </props> </property> </bean> </beans>
transactionAttributes 事務(wù)屬性配置格式?prop格式:PROPAGATION,ISOLATION,readOnly,-Exception,+Exception
1) PROPAGATION 傳播行為
2) ISOLATION 隔離級(jí)別?
3) readOnly : 僅僅讀事務(wù)。不能進(jìn)行改動(dòng)操作
4) -Exception : 發(fā)生這些異常回滾事務(wù)?
5) +Exception : 發(fā)生這些異常仍然提交事務(wù)?
<prop key="*">PROPAGATION_REQUIRED,+java.lang.ArithmeticException</prop> ?發(fā)生java.lang.ArithmeticException 事務(wù)也會(huì)提交
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop> 事務(wù)是僅僅讀,不能進(jìn)行改動(dòng)操作 ?
3、 聲明式事務(wù)管理 (使用XML配置聲明式事務(wù) 基于tx/aop)
導(dǎo)入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"/> <!-- 配置數(shù)據(jù)源 --> <!-- c3p0數(shù)據(jù)源 --> <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 , 將數(shù)據(jù)源注入到j(luò)dbcTemplate --> <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> <!-- 事務(wù)管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 通過tx:advice 配置事務(wù)管理增強(qiáng) --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- 配置事務(wù)屬性 --> <tx:attributes> <!-- 對(duì)哪個(gè)方法用事務(wù)管理 --> <tx:method name="transfer" propagation="REQUIRED" isolation="DEFAULT" read-only="false" /> </tx:attributes> </tx:advice> <!-- 配置aop --> <aop:config proxy-target-class="false"> <!-- 配置切點(diǎn) --> <aop:pointcut expression="execution(* service.AccountServiceImpl2.*(..))" id="mytransactionpointcut"/> <!-- 將一個(gè)Advice作為 一個(gè)切面 Advisor --> <!-- 對(duì) mytransactionpointcut 切點(diǎn) 進(jìn)行 txAdvice 增強(qiáng) --> <aop:advisor advice-ref="txAdvice" pointcut-ref="mytransactionpointcut"/> </aop:config> </beans>
4、聲明式事務(wù)管理 (使用注解配置 )
對(duì)須要管理事務(wù)的方法,加入注解@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 隔離級(jí)別
readOnly=false 是否僅僅讀
rollbackFor=ArithmeticException.class 發(fā)生異常回滾?
noRollbackFor=xxx.class 發(fā)生異常 仍然提交事務(wù)?
applicationContext4.xml
版權(quán)聲明:本文博主原創(chuàng)文章。博客,未經(jīng)同意不得轉(zhuǎn)載。
轉(zhuǎn)載于:https://www.cnblogs.com/blfshiye/p/4872944.html
總結(jié)
以上是生活随笔為你收集整理的Spring 事情具体详尽的解释的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FineReport——JS二次开发(局
- 下一篇: JSPatch – 动态更新iOS AP