spring系统学习--5事务控制
2021-04-25 07:29
标签:date 建立 creat 测试 pat value from ble 业务逻辑 spring配置文件内容: 业务逻辑层实现类: 测试类代码: 事务属性补充图片: spring配置文件代码: 需要事务控制的类需要添加@Transactional注解: 测试类代码: 该注解的属性和xml中的属性含义一致。该注解可以出现在接口上,类上和方法上。 出现接口上,表示该接口的所有实现类都有事务支持。 出现在类上,表示类中所有方法有事务支持 出现在方法上,表示方法有事务支持。 以上三个位置的优先级:方法>类>接口。 spring系统学习--5事务控制 标签:date 建立 creat 测试 pat value from ble 业务逻辑 原文地址:https://www.cnblogs.com/luzhanshi/p/13258595.html最原始的事务控制
// 注册驱动
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
// Class.forName("com.mysql.jdbc.Driver");
// 获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/spring5?useSSL=false", "root", "admin123");
// Connection对象可以设置事务提交方式:分为自动提交和手动提交;默认是自动提交
connection.setAutoCommit(false);
// 获取预处理对象
PreparedStatement preparedStatement = connection.prepareStatement("insert into account (name,money)values (?,?)");
preparedStatement.setString(1,"ccc");
preparedStatement.setFloat(2,1555f);
int i = preparedStatement.executeUpdate();
connection.commit();
System.out.println(i);
preparedStatement.close();
connection.close();
Spring事务模板使用
bean id="TransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
property name="dataSource" ref="comboPooledDataSource">property>
bean>
bean class="org.springframework.transaction.support.TransactionTemplate" id="transactionTemplate">
property name="transactionManager" ref="TransactionManager">property>
bean>
bean id="accountServiceImpl" class="service.impl.AccountServiceImpl">
property name="accountDao" ref="accountDao">property>
property name="transactionTemplate" ref="transactionTemplate">property>
bean>
bean id="comboPooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
property name="driverClass" value="com.mysql.jdbc.Driver">property>
property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring5">property>
property name="user" value="root">property>
property name="password" value="admin123">property>
bean>
//账户业务层实现类
public class AccountServiceImpl implements AccountService {
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
// 声明事务控制模板
private TransactionTemplate transactionTemplate;
public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
this.transactionTemplate = transactionTemplate;
}
@Override
public void transfer(String sourseName, String targetName, Float money) {
transactionTemplate.execute(new TransactionCallback
public class Client {
public static void main(String[] args) {
// 获取容器
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
AccountServiceImpl accountServiceImpl = (AccountServiceImpl) context.getBean("accountServiceImpl");
accountServiceImpl.transfer("aaa","bbb",100f);
context.close();
}
Spring基于XML的声明式事务控制(配置方式)重点(开发中首选)
需要事务控制的代码:
//账户业务层实现类
public class AccountServiceImpl implements AccountService {
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
@Override
public void transfer(String sourseName, String targetName, Float money) {
// 根据账户名查询对应的账户
Account sourceAccount = accountDao.findAccountByName(sourseName);
Account targetAccount = accountDao.findAccountByName(targetName);
// 转出账户减钱,转入账户加钱
sourceAccount.setMoney(sourceAccount.getMoney() - money);
targetAccount.setMoney(targetAccount.getMoney() + money);
// 更新两个账户
accountDao.updateAccount(sourceAccount);
// 模拟异常
int i = 1 / 0;
accountDao.updateAccount(targetAccount);
}
@Override
public Account findAccountById(Integer id) {
return accountDao.findAccountById(id);
}
}
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: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">
bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
property name="dataSource" ref="comboPooledDataSource">property>
bean>
bean id="comboPooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
property name="driverClass" value="com.mysql.jdbc.Driver">property>
property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring5">property>
property name="user" value="root">property>
property name="password" value="admin123">property>
bean>
bean id="accountServiceImpl" class="service.impl.AccountServiceImpl">
property name="accountDao" ref="accountDao">property>
property name="transactionTemplate" ref="transactionTemplate">property>
bean>
bean id="accountDao" class="dao.impl.AccountDaoImpl">
property name="jdbcTemplate" ref="jdbcTemplate">property>
property name="dataSource" ref="comboPooledDataSource">property>
bean>
bean id="TransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
property name="dataSource" ref="comboPooledDataSource">property>
bean>
tx:advice id="txAdvice" transaction-manager="TransactionManager">
tx:attributes>
tx:method name="*" read-only="false"/>
tx:method name="find*" read-only="true"/>
tx:attributes>
tx:advice>
aop:config>
aop:pointcut id="pt" expression="execution(* service..*.*(..))"/>
aop:advisor advice-ref="txAdvice" pointcut-ref="pt">aop:advisor>
aop:config>
beans>
测试代码:
public class Client {
public static void main(String[] args) {
// 获取容器
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
AccountService accountService = (AccountService) context.getBean("accountServiceImpl");
accountService.transfer("aaa","bbb",100f);
context.close();
}
}
Spring基于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"
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:component-scan base-package="service">context:component-scan>
context:component-scan base-package="dao">context:component-scan>
bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
property name="dataSource" ref="comboPooledDataSource">property>
bean>
bean id="comboPooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
property name="driverClass" value="com.mysql.jdbc.Driver">property>
property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring5">property>
property name="user" value="root">property>
property name="password" value="admin123">property>
bean>
bean id="TransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
property name="dataSource" ref="comboPooledDataSource">property>
bean>
tx:annotation-driven transaction-manager="TransactionManager">tx:annotation-driven>
beans>
//账户业务层实现类
@Service("accountService")
/**
* @Transactional可以出现在接口上,类上和方法
* 接口上:表示该接口中的所有方法,实现类中重写的方法都有事务
* 类上:表示该类中所有的方法都有事务
* 方法上:表示当前方法有事务
* 优先级:就近原则。
* 方法>类>接口
*/
@Transactional(readOnly = false)
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao accountDao;
@Override
public void transfer(String sourseName, String targetName, Float money) {
// 根据账户名查询对应的账户
Account sourceAccount = accountDao.findAccountByName(sourseName);
Account targetAccount = accountDao.findAccountByName(targetName);
// 转出账户减钱,转入账户加钱
sourceAccount.setMoney(sourceAccount.getMoney() - money);
targetAccount.setMoney(targetAccount.getMoney() + money);
// 更新两个账户
accountDao.updateAccount(sourceAccount);
// 模拟异常
int i = 1 / 0;
accountDao.updateAccount(targetAccount);
}
@Override
public Account findAccountById(Integer id) {
return accountDao.findAccountById(id);
}
}
public class Client {
public static void main(String[] args) {
// 获取容器
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
AccountService accountService = (AccountService) context.getBean("accountService");
accountService.transfer("aaa","bbb",100f);
Account account = accountService.findAccountById(1);
System.out.println(account);
context.close();
}
}
基于纯注解的声明式事务控制(配置方式)重点
创建一个类用于加载spring的配置并指定要扫描的包
/**
* 用于初始化spring容器的配置类
*/
@Configuration
@ComponentScan(basePackages="com.itheima")
public class SpringConfiguration {
}
创建业务层接口和实现类并使用注解让spring管理
/**
* 账户的业务层实现类
*/
@Service("accountService")
public class AccountServiceImpl implements IAccountService {
@Autowired
private IAccountDao accountDao;
@Override
public Account findAccountById(Integer id) {
return accountDao.findAccountById(id);
}
@Override
public void transfer(String sourceName, String targeName, Float money) {
//1.根据名称查询两个账户
Account source = accountDao.findAccountByName(sourceName);
Account target = accountDao.findAccountByName(targeName);
//2.修改两个账户的金额
source.setMoney(source.getMoney()-money);//转出账户减钱
target.setMoney(target.getMoney()+money);//转入账户加钱
//3.更新两个账户
accountDao.updateAccount(source);
int i=1/0;
accountDao.updateAccount(target);
}
}
创建Dao接口和实现类并使用注解让spring管理
Dao层接口和AccountRowMapper与基于xml配置的时候相同。略
@Repository("accountDao")
public class AccountDaoImpl implements IAccountDao {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public Account findAccountById(Integer id) {
List list = jdbcTemplate.query("select * from account where id = ? ",new AccountRowMapper(),id);
return list.isEmpty()?null:list.get(0);
}
@Override
public Account findAccountByName(String name) {
List list = jdbcTemplate.query("select * from account where name = ? ",new AccountRowMapper(),name);
if(list.isEmpty()){
return null;
}
if(list.size()>1){
throw new RuntimeException("结果集不唯一,不是只有一个账户对象");
}
return list.get(0);
}
@Override
public void updateAccount(Account account) {
jdbcTemplate.update("update account set money = ? where id = ? ",account.getMoney(),account.getId());
}
}
使用@Bean注解配置数据源
@Bean(name = "dataSource")
public DataSource createDS() throws Exception {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUsername("root");
dataSource.setPassword("123");
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://spring3_day04");
return dataSource;
}
使用@Bean注解配置配置事务管理器
@Bean
public PlatformTransactionManager
createTransactionManager(@Qualifier("dataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
使用@Bean注解配置JdbcTemplate
@Bean
public JdbcTemplate createTemplate(@Qualifier("dataSource") DataSource dataSource)
{
return new JdbcTemplate(dataSource);
}
在需要控制事务的业务层实现类上使用@Transactional注解
@Service("accountService")
@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
public class AccountServiceImpl implements IAccountService {
@Autowired
private IAccountDao accountDao;
@Override
public Account findAccountById(Integer id) {
return accountDao.findAccountById(id);
}
@Override
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public void transfer(String sourceName, String targeName, Float money) {
//1.根据名称查询两个账户
Account source = accountDao.findAccountByName(sourceName);
Account target = accountDao.findAccountByName(targeName);
//2.修改两个账户的金额
source.setMoney(source.getMoney() - money);//转出账户减钱
target.setMoney(target.getMoney() + money);//转入账户加钱
//3.更新两个账户
accountDao.updateAccount(source);
//int i=1/0;
accountDao.updateAccount(target);
}
}
使用@EnableTransactionManagement开启spring对注解事务的的支持
@Configuration
@EnableTransactionManagement
public class SpringTxConfiguration {
//里面配置数据源,配置JdbcTemplate,配置事务管理器。在之前的步骤已经写过了。
}
创建业务层接口和实现类并使用注解让spring管理