Spring中的事务控制

一,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: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">
<!--配置账户的业务层-->
<bean id="accountService" class="com.lzw.service.impl.AccountServiceImpl">
<!--给accountDao注入数据-->
<property name="accountDao" ref="accountDao"></property>
</bean>

<!--配置账户的持久层-->
<bean id="accountDao" class="com.lzw.dao.impl.AccountDaoImpl">
<!--给AccountDaoImpl中的jdbcTemplate注入数据-->
<property name="dataSource" ref="dataSource"></property>
</bean>


<!--配置spring内置数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
</bean>

<!--spring中基于xml的声明式事务控制配置步骤
配置事务管理器
配置事务通知
导入事务的约束 tx名称空间约束,同时也需要aop的
使用tx:advice标签配置事务通知
属性
id 给事务唯一通知
transaction-manager 给事务通知一个事务管理器用
配置aop通用切入点表达式
     建立事务通知和切入点表达式对应关系
     配置事务属性
在事务的通知tx:advice标签内部
-->
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>

<!--配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--配置事务属性
isolation 用于指定隔离级别 默认是default 表示使用数据库的隔离级别
propagation 指定事务的传播行为 默认是required 表示一定有事务 增删改的选择 查询方法可以选择 supports
read-only 指定事务是否只读 只有查询方法才能设置为true 默认是false
timeout 指定事务的超时时间 默认是-1 表示永不超时 如果指定了数据 单位为秒
rollback-for 用于指定一个异常 当产生异常 事务回滚 产生其他异常 事务不回滚 没有默认值 任何异常都回滚
no-rollback-for 指定一个异常 当产生异常时 事务不回滚 产生其他异常时 事务回滚 没有默认值 表示任何异常都回滚
-->
<tx:attributes>
<tx:method name="transfer" propagation="REQUIRED" read-only="false"/>
</tx:attributes>
</tx:advice>

<!--配置aop-->
<aop:config>
<!--配置切入点表达式-->
<aop:pointcut id="pt1" expression="execution(* com.lzw.service.impl.*.*(..))"></aop:pointcut>
<!--建立切入点表达式和事务通知的对应关系-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"></aop:advisor>
</aop:config>
</beans>

二,Spring中基于纯注解文件配置事务管理

package com.lzw.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
* spring中的配置类 相当于bean.xml
*/
@Configuration //配置类
@ComponentScan("com.lzw") //创建srping容器时通知要扫描的包
@Import({JdbcConfig.class,TransactionManagerConfig.class}) //导入其他配置类
@PropertySource(value="jdbcConfig.properties") //引入外部资源
@EnableTransactionManagement //注解开启spring事务支持
public class SpringConfiguration {}

 

package com.lzw.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import javax.sql.DataSource;

/**
* 连接数据库相关的数据类
*/
public class JdbcConfig {

//注入基本数据类型和String类型数据 使用el表达式 注入数据
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;

/**
* 创建jdbctemplate对象
* @param dataSource
* @return
*/
//该注解只能写在方法上,表明使用此方法创建一个对象,并放入spring容器
@Bean(name="jdbcTemplate")
public JdbcTemplate createJdbcTemplate(DataSource dataSource){
return new JdbcTemplate(dataSource);
}

/**
* 创建数据源
* @return
*/
@Bean(name="dataSource")
public DataSource createDataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}

package com.lzw.config;

import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

/**
* 和事务相关的配置
*/
public class TransactionManagerConfig {

/**
* 创建数据管理器对象
* @param dataSource
* @return
*/
@Bean(name="transactionManager")
public PlatformTransactionManager createTransactionManager(DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
}

package com.lzw.service.impl;

import com.lzw.dao.IAccountDao;
import com.lzw.domian.Account;
import com.lzw.service.IAccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
* 业务层
*/
@Service("accountService") //创建accountService放入容器中
@Transactional(propagation= Propagation.SUPPORTS,readOnly=true)//只读型事务的配置
public class AccountServiceImpl implements IAccountService {

@Autowired //自动按照成员变量类型注入
private IAccountDao accountDao;


public Account findAccountById(Integer accountId) {

return accountDao.findAccountById(accountId);

}
@Transactional(propagation = Propagation.REQUIRED,readOnly = false)//需要的是读写型事务配置
public void transfer(String sourceName, String targetName, Float money) {
//根据名称查出转出账户
Account source = accountDao.findAccountByName(sourceName);
//根据名称查出转入账户
Account target = accountDao.findAccountByName(targetName);
//转出账户减钱
source.setMoney(source.getMoney() - money);
//转入账户加前
target.setMoney(target.getMoney() + money);
//更新转出账户
accountDao.updateAccount(source);

// int i = 1 / 0;
//更新转入账户
accountDao.updateAccount(target);
}
}

package com.lzw.dao.impl;

import com.lzw.dao.IAccountDao;
import com.lzw.domian.Account;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
* 账户持久层实现类
*/
@Repository("accountDao")
public class AccountDaoImpl implements IAccountDao {

@Autowired
private JdbcTemplate jdbcTemplate;
/**
* 根据id查询用户
* @param id
* @return
*/
public Account findAccountById(Integer id) {
List<Account> accountList = jdbcTemplate.query("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),id);
return (accountList.isEmpty()? null : accountList.get(0));
}

/**
* 根据name查询id
* @param accountname
* @return
*/
public Account findAccountByName(String accountname) {
List<Account> accountList = jdbcTemplate.query("select * from account where name = ?",
new BeanPropertyRowMapper<Account>(Account.class),accountname);
if(accountList.isEmpty()){
return null;
}
if(accountList.size() > 1){
throw new RuntimeException("结果集不唯一");
}
return accountList.get(0);
}

/**
* 更新用户
* @param account
*/
public void updateAccount(Account account) {
jdbcTemplate.update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());
}
}
在实际开发我们更常用的是xml和注解的结合使用


posted @ 2019-09-11 17:31  文所未闻  阅读(1633)  评论(0编辑  收藏  举报