spring31-1: 事务-传播行为
传播行为:在两个事务之间如何共享事务。
PROPAGATION_REQUIRED
支持当前事务,A如果有事务,B将使用该事务。
如果A没有事务,B将创建一个新的事务。
PROPAGATION_SUPPORTS
支持当前事务,A如果有事务,B将使用该事务。
如果A没有事务,B将以非事务执行。(你有,我也有; 你没有,我也就没有)
PROPAGATION_MANDATORY
支持当前事务,A如果有事务,B将使用该事务。
如果A没有事务,B将抛异常。
PROPAGATION_REQUIRES_NEW
如果A有事务, 将A的事务挂起。 B创建一个新的事务。
如果A没有事务,B将创建一个新的事务。
PROPAGATION_NOT_SUPPORTED
如果A有事务, 将A的事务挂起。B将以非事务执行。
如果A没有事务,B将以非事务执行。
PROPAGATION_NEVER
如果A有事务,B将抛异常。
如果A没有事务,B将以非事务执行。
PROPAGATION_NESTED
A和B底层采用保存点机制,形成嵌套事务。
手动管理事物
spring底层使用TransactionTemplate事物模板进行操作。
操作: 1. service需要获得TransactionTemplate 2. spring配置模板,并注入给service 3. 模板需要注入事务管理器 4. 配置事务管理器, DataSourceTransactionManager
Dao类
package com.atchina.d_spring_tx2.dao;public interface AccountDao {// 汇款public void in(String inner, Double money);// 收款public void out(String outter, Double money); }package com.atchina.d_spring_tx2.dao.impl;import org.springframework.jdbc.core.support.JdbcDaoSupport;import com.atchina.d_spring_tx.dao.AccountDao;public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{@Overridepublic void in(String inner, Double money) {String sql = "update bankaccount a set money = money + ? where username = ? ";this.getJdbcTemplate().update(sql, money, inner);}@Overridepublic void out(String outter, Double money) {String sql = "update bankaccount a set money = money - ? where username = ? ";Object[] objs = {money, outter};this.getJdbcTemplate().update(sql, objs);} }service类
// 接口 package com.atchina.d_spring_tx2.service;public interface AccountService {public void transfer(String outter, String inner, Double money); }// 实现类 package com.atchina.d_spring_tx2.service.impl;import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate;import com.atchina.d_spring_tx.dao.AccountDao; import com.atchina.d_spring_tx.service.AccountService;public class AccountServiceImpl implements AccountService{private AccountDao accountDao;private TransactionTemplate transactionTemplate;//spring注入模板public void setTransactionTemplate(TransactionTemplate transactionTemplate) {this.transactionTemplate = transactionTemplate;}public void setAccountDao(AccountDao accountDao) {this.accountDao = accountDao;}@Overridepublic void transfer(final String outter, final String inner, final Double money) {transactionTemplate.execute( new TransactionCallbackWithoutResult() {@Overrideprotected void doInTransactionWithoutResult(TransactionStatus status) {accountDao.out(outter, money);int a = 5/0;accountDao.in(inner, money);}});} }spring配置文件
<?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:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!-- 配置数据源c3p0 --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property><property name="jdbcUrl" value="jdbc:oracle:thin:@//127.0.0.1:1521/orcl"></property><property name="user" value="scott"></property><property name="password" value="123456"></property></bean><!-- 创建模板,需要注入数据源 --><bean id="accountDao" class="com.atchina.d_spring_tx2.dao.impl.AccountDaoImpl"><property name="dataSource" ref="dataSource"></property></bean><!-- 配置dao --><bean id="accountService" class="com.atchina.d_spring_tx2.service.impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"></property><property name="transactionTemplate" ref="transactionTemplate"></property></bean><!-- 创建模板 --><bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"><property name="transactionManager" ref="txManager"></property></bean> <!-- 配置事务管理器, 管理器需要事务,事务从Connection获得,连接从DataSource获得 --><bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean> </beans>测试类:
package com.atchina.d_spring_tx2;import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;import com.atchina.d_spring_tx.service.AccountService;public class TestTx {@Testpublic void test(){String xmlPath = "com/atchina/d_spring_tx2/applicationContext.xml";ApplicationContext ac = new ClassPathXmlApplicationContext(xmlPath);AccountService accountService = (AccountService)ac.getBean("accountService");accountService.transfer("tom", "jerry", 500.0);} }工厂bean生成代理:半自动
配置文件
<?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:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!-- 配置数据源c3p0 --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property><property name="jdbcUrl" value="jdbc:oracle:thin:@//127.0.0.1:1521/orcl"></property><property name="user" value="scott"></property><property name="password" value="123456"></property></bean><!-- 创建模板,需要注入数据源 --><bean id="accountDao" class="com.atchina.d_spring_tx3.dao.impl.AccountDaoImpl"><property name="dataSource" ref="dataSource"></property></bean><!-- 配置dao --><bean id="accountService" class="com.atchina.d_spring_tx3.service.impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"></property></bean><bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><!-- service代理对象1.proxyInterfaces 接口,2.target 目标类3.transactionManager 事务管理器4.transactionAttributes: 事务属性prop.key: 确定哪些方法使用当前事务配置prop.text: 用于配置事务详情格式: PROPAGATION,ISOLATION,readOnly,-Exception,+Exception传播行为 隔离级别 是否只读 有异常回滚 有异常提交例如: <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT</prop> 默认传播行为 ,隔离级别 <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT,+java.lang.ArithmeticException</prop>--><bean id="proxyAccountService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"><property name="proxyInterfaces" value="com.atchina.d_spring_tx3.service.AccountService"></property><property name="target" ref="accountService"></property><property name="transactionManager" ref="dataSourceTransactionManager"></property><property name="transactionAttributes"><props><prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly</prop></props></property></bean> </beans>测试类:
public class TestTx {@Testpublic void test(){String xmlPath = "com/atchina/d_spring_tx3/applicationContext.xml";ApplicationContext ac = new ClassPathXmlApplicationContext(xmlPath);AccountService accountService = (AccountService)ac.getBean("proxyAccountService");accountService.transfer("tom", "jerry", 500.0);} }AOP配置,基于xml
在spring xml配置aop自动生成代理,进行事务的管理
1.配置管理器 2. 配置事务详情 3.配置aop
<?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:tx="http://www.springframework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"><!-- 配置数据源c3p0 --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property><property name="jdbcUrl" value="jdbc:oracle:thin:@//127.0.0.1:1521/orcl"></property><property name="user" value="scott"></property><property name="password" value="123456"></property></bean><!-- 创建模板,需要注入数据源 --><bean id="accountDao" class="com.atchina.d_spring_tx4.dao.impl.AccountDaoImpl"><property name="dataSource" ref="dataSource"></property></bean><!-- 配置dao --><bean id="accountService" class="com.atchina.d_spring_tx4.service.impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"></property></bean><!-- 事务管理 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><!-- 事务详情(事务通知) 在aop筛选基础上,对筛选出来的方法进行管理<tx:attributes> 用于配置事务详情<tx:method name=""/>详情具体配置propagation 传播行为isolation 隔离级别--><tx:advice id="advice" transaction-manager="transactionManager"><tx:attributes><tx:method name="transfer" propagation="REQUIRED" isolation="DEFAULT"/></tx:attributes></tx:advice><!-- aop编程 --><aop:config><aop:advisor advice-ref="advice" pointcut="execution(* com.atchina.d_spring_tx4.service..*.*(..))"/></aop:config> </beans>AOP配置,基于注解
1. 配置事务管理器,并将事务管理器交给spring
2. 在目标类或目标方法添加注解即可 @Transactional
配置文件
<?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:tx="http://www.springframework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"><!-- 配置数据源c3p0 --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property><property name="jdbcUrl" value="jdbc:oracle:thin:@//127.0.0.1:1521/orcl"></property><property name="user" value="scott"></property><property name="password" value="123456"></property></bean><!-- 创建模板,需要注入数据源 --><bean id="accountDao" class="com.atchina.d_spring_tx5.dao.impl.AccountDaoImpl"><property name="dataSource" ref="dataSource"></property></bean><!-- 配置dao --><bean id="accountService" class="com.atchina.d_spring_tx5.service.impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"></property></bean><!-- 事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><!-- 将事物管理器交给spring --><tx:annotation-driven transaction-manager="transactionManager"/> </beans>service类 加上@Transactional注解
package com.atchina.d_spring_tx5.service.impl;import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional;import com.atchina.d_spring_tx5.dao.AccountDao; import com.atchina.d_spring_tx5.service.AccountService;@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT,noRollbackForClassName={"java.lang.ArithmeticException"}) public class AccountServiceImpl implements AccountService{private AccountDao accountDao;public void setAccountDao(AccountDao accountDao) {this.accountDao = accountDao;}@Overridepublic void transfer(String outter, String inner, Double money) {this.accountDao.out(outter, money);int a = 5/0;this.accountDao.in(inner, money);} }与junit整合
package com.atchina.d_spring_tx_test;import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import com.atchina.d_spring_tx_test.service.AccountService;@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:com/atchina/d_spring_tx_test/applicationContext.xml") public class TestTx {@Autowired // 与junit整合,不需要在spring.xml配置扫描private AccountService accountService;@Testpublic void test(){ // String xmlPath = "com/atchina/d_spring_tx_test/applicationContext.xml"; // ApplicationContext ac = new ClassPathXmlApplicationContext(xmlPath); // // AccountService accountService = (AccountService)ac.getBean("accountService");accountService.transfer("tom", "jerry", 500.0);} }
总结
以上是生活随笔为你收集整理的spring31-1: 事务-传播行为的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: Java中的某些接口为什么没有任何方法?
- 下一篇: javac,使用-d .与省略-d的区别