除了自己拿到一个connection
再自己手动设置开启事务、提交事务、回滚事务、释放事务。在spring中,它为我们提供了事务控制的一组api
既然是使用spring框架使用因此,建议使用该方法。
AccountDao.java 持久层
package dao.impl;
import dao.IAccountDao;
import domain.Account;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import java.util.List;
public class AccountDao extends JdbcDaoSupport implements IAccountDao {
public Account selectAccountByName(String name) {
List<Account> lists = super.getJdbcTemplate().query("select * from account where name = ?", new BeanPropertyRowMapper<Account>(Account.class),name);
if(lists == null || lists.size() > 1){
throw new RuntimeException("不存在或者结果集不唯一");
}
return lists.get(0);
}
public Account selectAccountById(Integer id) {
return super.getJdbcTemplate().query("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class),id).get(0);
}
public void updateAccount(Account account) {
super.getJdbcTemplate().update("update account set name = ?,money = ? where id = ?",account.getName(),account.getMoney(),account.getId());
}
}
AccountService 业务层
package service.impl;
import dao.IAccountDao;
import domain.Account;
import service.IAccountService;
import java.util.List;
public class AccountServiceImpl implements IAccountService {
IAccountDao accountDao;
public void setAccountDao(IAccountDao accountDao) {
this.accountDao = accountDao;
}
public Account selectAccountById(Integer id) {
return accountDao.selectAccountById(id);
}
public void transfer(String giveName, String reName, double money) {
// 1. 找到两个用户。确定存在
Account account = accountDao.selectAccountByName(giveName);
Account account1 = accountDao.selectAccountByName(reName);
// 2. 给两个用户加钱、减钱
account.setMoney(account.getMoney() - money);
account1.setMoney(account1.getMoney() + money);
// 3. 更新
accountDao.updateAccount(account);
// 用于模拟转账出现错误和不产生错误,事务能否正常运行
int a = 1/0;
accountDao.updateAccount(account1);
}
}
<bean id="accountDao" class="dao.impl.AccountDao">
<!-- 这是因为继承了JdbcDaoSupport它需要数据源 -->
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="accountService" class="service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
<!--2. 配置事务管理器 -->
<bean id="drivcerManger" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--3. 配置事务的通知 -->
<!--
id:唯一标识
transaction-manager:给事务通知一个事务管理器
-->
<tx:advice id="txAdvice" transaction-manager="drivcerManger"></tx:advice>
<!--4. 配置AOP -->
<aop:config>
<aop:pointcut expression="execution(* service.impl.*.*(..))" id="pt1"/>
<!-- 5. 建立切入点表达式和切入点表达式的对应关系 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/>
</aop:config>
<tx:attributes>
<tx:method name="*" read-only="false" propagation="REQUIRED"/>
<tx:method name="select*" read-only="true" propagation="SUPPORTS"/>
</tx:attributes>
<?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: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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--将对象放入ioc容器 -->
<bean id="accountDao" class="dao.impl.AccountDao">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="accountService" class="service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
<!--1. 配置事务管理器 -->
<bean id="drivcerManger" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--2. 配置事务的通知 -->
<!--
id:唯一标识
transaction-manager:给事务通知一个事务管理器
-->
<tx:advice id="txAdvice" transaction-manager="drivcerManger">
<!-- 5. 配置事务的属性 -->
<!--
isolation:用于指定事务的隔离级别。默认值是DEFAULT.表示使用数据库的默认隔离级别。
propagation:用于指定事务的传播行为。默认值是REQUIRED.表示一定会有事务, 增册改的选择。查询方法可以选择SUPPORTS。
read-only:用于指定事务是否只读。只有查询方法才能设置为true.默认值是false.表示读写。
timeout:用于指定事务的超时时间,默认值是-1,表示永不超时。如果指定了数值,以秒为单位。
rollback-for:用于指定一个异常, 当产生该异常时,事务回滚。产生其他异常时,事务不回滚。设有状认值。表示任何异常都回滚。
no-rollback-for:用于指定一个异常, 当产生该异常时,事务不回滚, 产生其他异常时事务回滚。 没有默认值。表示任何异常都回滚。
-->
<tx:attributes>
<tx:method name="*" read-only="false" propagation="REQUIRED"/>
<tx:method name="select*" read-only="true" propagation="SUPPORTS"/>
</tx:attributes>
</tx:advice>
<!--3. 配置AOP -->
<aop:config>
<aop:pointcut expression="execution(* service.impl.*.*(..))" id="pt1"/>
<!-- 4. 建立切入点表达式和切入点表达式的对应关系 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/>
</aop:config>
<!--配置事务管理器需要的数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/bilibili_ioc?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
</beans>
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- oldu.cn 版权所有 浙ICP备2024123271号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务