create databases spring_date;
use spring_date;
create table account(
id int primary key auto_increment,
username varchar(50),
money int);
insert into account(username,money) values('jack','10000')
insert into account(username,money) values('rose','10000')
package com.itheima.dao;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{// 继承JdbcDaoSupport,之后只需要注入数据源,底层自动创建模板
@Override
public void out(String outer, int money) {//汇款
// TODO 自动生成的方法存根
this.getJdbcTemplate().update("update account set money=money-? where username=?", money,outer);//使用JdbcTemplate模板操作数据库
}
@Override
public void in(String inner, int money) {//收款
// TODO 自动生成的方法存根
this.getJdbcTemplate().update("update account set money=money+? where username=?", money,inner);
}
}
package com.itheima.service.impl;
import com.itheima.dao.AccountDao;
import com.itheima.service.AccountService;
public class AccountServicImpl implements AccountService {
private AccountDao accountDao;
public void setAccountdao(AccountDao accountdao) {//set dao
this.accountDao = accountdao;
}
@Override
public void transfer(String outer, String inner, int money) {//转账
// TODO 自动生成的方法存根
accountDao.out(outer, money);
accountDao.in(inner, money);
}
}
<?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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- properti -->
<!--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://localhost:3306/spring_date"></property>
<property name="user" value="root"></property>
<property name="password" value="123456"></property>
</bean>
<!-- dao -->
<bean id="accountDao" class="com.itheima.dao.AccountDaoImpl">
<property name="dataSource" ref="datasource"></property>
</bean>
<!-- service -->
<bean id="accountService" class="com.itheima.service.impl.AccountServicImpl">
<property name="accountdao" ref="accountDao"></property>
</bean>
</beans>
package com.itheima;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.itheima.service.AccountService;
public class TestApp {
@Test
public void demo01() {
//加载配置文件
String xmlpath="applicationContext.xml";
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(xmlpath);
AccountService accountService= applicationContext.getBean("accountService",AccountService.class);
accountService.transfer("jack", "rose", 1000);/测试
}
}
能实现转账功能,但如果在转账过程中间出现异常情况,就会出现只有汇款人金额已经减少,但收款人金额没有增加的现象
//需要spring 注入模板
private TransactionTemplate transactionTemplate;
public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
this.transactionTemplate = transactionTemplate;
}
@Override
public void transfer(String outer, String inner, int money) {
//调用模板的执行方法,使用事务回调匿名内部类进行增删改操作
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus arg0) {
// TODO 自动生成的方法存根
accountDao.out(outer, money);
accountDao.in(inner, money);
}
});
<!-- service 注入dao和transactionTemplate事务模板 -->
<bean id="accountService" class="com.itheima.service.impl.AccountServicImpl">
<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>
能实现转账功能,但如果在转账过程中间出现异常情况,事务就会回滚,取消写入数据库
<!-- 4.service 代理对象
4.1 proxyInterfaces 接口
4.2 target 目标类
4.3 transactionManager 事务详情
4.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.itheima.service.AccountService"></property>
<property name="target" ref="accountService"></property>
<property name="transactionManager" ref="txManager"></property>
<property name="transactionAttributes">
<props>
<prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT</prop>
</props>
</property>
</bean>
<!-- 5.事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
public class TestApp {
@Test
public void demo01() {
String xmlpath="applicationContext.xml";
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(xmlpath);
AccountService accountService= applicationContext.getBean("proxyAccountService",AccountService.class);
accountService.transfer("jack", "rose", 1000);
}
}
<?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"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- properti -->
<context:property-placeholder location="classpath:jdbcInfo.properties"/>
<!--dataSource -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- dao -->
<bean id="accountDao" class="com.itheima.dao.AccountDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- service -->
<bean id="accountService" class="com.itheima.service.impl.AccountServicImpl">
<property name="accountdao" ref="accountDao"></property>
</bean>
<!-- 4事务管理 -->
<!-- 4.1 事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 4.2 事务详情 ,在aop筛选基础上,对ABC三个确定使用什么事务。例如AC读写、B只读等
<tx:attributes> 用于配置事务详情
<tx:method name=""/> 详情具体配置
-->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="transfer" propagation="REQUIRED" isolation="DEFAULT"/>
</tx:attributes>
</tx:advice>
<!-- 4.2 AOP编程,目标类有ABCD(4个连接点),切入点表达式确定增强的连接器 -->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.itheima.service..*(..))"/>
</aop:config>
</beans>
<?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"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- properti -->
<context:property-placeholder location="classpath:jdbcInfo.properties"/>
<!--dataSource -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- dao -->
<bean id="accountDao" class="com.itheima.dao.AccountDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- service -->
<bean id="accountService" class="com.itheima.service.impl.AccountServicImpl">
<property name="accountdao" ref="accountDao"></property>
</bean>
<!-- 4.事务管理 -->
<!-- 4.1 事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 4.2将管理器交予spring
* transaction-manager 配置事务管理器
* proxy-target-class
true :底层强制使用cglib代理
-->
<tx:annotation-driven transaction-manager="txManager" proxy-target-class="false"/>
</beans>
想在那配置事务在那个方法或类的上方添加@Transactional 注解即可
@Transactional
public class AccountServicImpl implements AccountService {
原文:https://www.cnblogs.com/a1737301376/p/11234219.html