Spring事务
2021-03-28 18:26
标签:方法 interface source required begin aop 连接 localhost 相关 事务Transaction就是一件事情,要做就要做完,如果中途出现问题就要恢复成最初状态。事务具备ACID四种特性,ACID是Atomic(原子性)、Consistency(一致性)、Isolation(隔离性)和Durability(持久性)的英文缩写: 事务传播行为就是多个事务方法调用时,如何定义方法间事务的传播,spring定义了七个传播级别: Spring事务 标签:方法 interface source required begin aop 连接 localhost 相关 原文地址:https://www.cnblogs.com/yfstudy/p/13622072.html一、事务认识
事务的传播特性
事务的隔离级别
事务导致结果
事务的实现方式
二、事务实现
基于 TransactionProxyFactoryBean实现
package Transaction.Entity;
/*
账户对象
*/
public class Account {
//账号ID
private int accountid;
//账号名称
private String name;
//金额
private String balance;
public int getAccountid() {
return accountid;
}
public void setAccountid(int accountid) {
this.accountid = accountid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBalance() {
return balance;
}
public void setBalance(String balance) {
this.balance = balance;
}
}
package Transaction.Entity;
/*
股票对象
*/
public class Stock {
//股票ID
private int stockid;
//股票名称
private String name;
//股数
private Integer count;
public int getStockid() {
return stockid;
}
public void setStockid(int stockid) {
this.stockid = stockid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
}
package Transaction.Entity;
/*
自定义异常
*/
public class BuyStockException extends Exception{
public BuyStockException() {
super();
}
public BuyStockException(String message) {
super(message);
}
}
package Transaction.Dao;
public interface AccountDao {
void addAccount(String name,double money);
void updateAccount(String name,double money,boolean isbuy);
}
package Transaction.Dao;
import Transaction.Dao.AccountDao;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
@Override
public void addAccount(String name, double money) {
String sql = "insert account(name,balance) values(?,?);";
this.getJdbcTemplate().update(sql,name,money);
}
@Override
public void updateAccount(String name, double money, boolean isbuy) {
String sql = "update account set balance=balance+? where name=?";
if(isbuy)
sql = "update account set balance=balance-? where name=?";
this.getJdbcTemplate().update(sql, money,name);
}
}
package Transaction.Dao;
public interface StockDao {
void addStock(String sname,int count);
void updateStock(String sname,int count,boolean isbuy);
}
package Transaction.Dao;
import Transaction.Dao.StockDao;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
public class StockDaoImpl extends JdbcDaoSupport implements StockDao {
@Override
public void addStock(String sname, int count) {
String sql = "insert into stock(name,count) values(?,?)";
this.getJdbcTemplate().update(sql,sname,count);
}
@Override
public void updateStock(String sname, int count, boolean isbuy) {
String sql = "update stock set count = count-? where name = ?";
if(isbuy)
sql = "update stock set count = count+? where name = ?";
this.getJdbcTemplate().update(sql, count,sname);
}
}
package Transaction.Service;
import Transaction.Entity.BuyStockException;
public interface BuyStockService {
//添加账户
public void addAccount(String accountname, double money);
//添加股票
public void addStock(String stockname, int amount);
//购买股票
public void buyStock(String accountname, double money, String stockname, int amount) throws BuyStockException;
}
package Transaction.Service;
import Transaction.Entity.BuyStockException;
import Transaction.Dao.AccountDao;
import Transaction.Dao.StockDao;
import org.springframework.transaction.annotation.Transactional;
public class BuyStockServiceImpl implements BuyStockService {
private AccountDao accountDao;
private StockDao stockDao;
public AccountDao getAccountDao() {
return accountDao;
}
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
public StockDao getStockDao() {
return stockDao;
}
public void setStockDao(StockDao stockDao) {
this.stockDao = stockDao;
}
@Override
public void addAccount(String accountname, double money) {
accountDao.addAccount(accountname,money);
}
@Override
public void addStock(String stockname, int amount) {
stockDao.addStock(stockname,amount);
}
@Override
public void buyStock(String accountname, double money, String stockname, int amount) throws BuyStockException {
boolean isBuy = true;
accountDao.updateAccount(accountname, money, isBuy);
if(isBuy==true){
throw new BuyStockException("购买股票发生异常");
}
stockDao.updateStock(stockname, amount, isBuy);
}
}
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-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-aop-4.2.xsd
">
context:property-placeholder location="classpath:jdbc.properties"/>
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">property>
property name="user" value="root">property>
property name="password" value="123456">property>
bean>
bean id="accountDao" class="Transaction.Dao.AccountDaoImpl">
property name="dataSource" ref="dataSource"/>
bean>
bean id="stockDao" class="Transaction.Dao.StockDaoImpl">
property name="dataSource" ref="dataSource"/>
bean>
bean id="buyStockService" class="Transaction.Service.BuyStockServiceImpl">
property name="accountDao" ref="accountDao">property>
property name="stockDao" ref="stockDao">property>
bean>
bean id="myTracnsactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
property name="dataSource" ref="dataSource">property>
bean>
bean id="serviceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
property name="transactionManager" ref="myTracnsactionManager">property>
property name="target" ref="buyStockService">property>
property name="transactionAttributes">
props>
prop key="add*">ISOLATION_DEFAULT,PROPAGATION_REQUIREDprop>
prop key="buyStock">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-BuyStockExceptionprop>
props>
property>
bean>
beans>
package Transaction;
import Transaction.Service.BuyStockService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
String resouce = "TransactionProxyFactoryBean.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(resouce);
BuyStockService buyStockService = (BuyStockService) applicationContext.getBean("serviceProxy");
buyStockService.addAccount("小郑", 5000);
buyStockService.addStock("知晓科技", 0);
/*try{
buyStockService.buyStock("小郑", 1000, "知晓科技", 100);
}catch (Exception e){
e.printStackTrace();
}*/
}
}
基于 @Transactional实现
package Transaction.Service;
import Transaction.Entity.BuyStockException;
import Transaction.Dao.AccountDao;
import Transaction.Dao.StockDao;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
public class BuyStockServiceImpl implements BuyStockService {
private AccountDao accountDao;
private StockDao stockDao;
public AccountDao getAccountDao() {
return accountDao;
}
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
public StockDao getStockDao() {
return stockDao;
}
public void setStockDao(StockDao stockDao) {
this.stockDao = stockDao;
}
@Override
@Transactional(isolation= Isolation.DEFAULT,propagation= Propagation.REQUIRED)
public void addAccount(String accountname, double money) {
accountDao.addAccount(accountname,money);
}
@Override
@Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED)
public void addStock(String stockname, int amount) {
stockDao.addStock(stockname,amount);
}
@Override
@Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED)
public void buyStock(String accountname, double money, String stockname, int amount) throws BuyStockException {
boolean isBuy = true;
accountDao.updateAccount(accountname, money, isBuy);
if(isBuy==true){
throw new BuyStockException("购买股票发生异常");
}
stockDao.updateStock(stockname, amount, isBuy);
}
}
bean id="myTracnsactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
property name="dataSource" ref="dataSource">property>
bean>
tx:annotation-driven transaction-manager="myTracnsactionManager"/>
基于Aspectj AOP实现
bean id="myTracnsactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
property name="dataSource" ref="dataSource">property>
bean>
tx:advice id="txAdvice" transaction-manager="myTracnsactionManager">
tx:attributes>
tx:method name="add*" isolation="DEFAULT" propagation="REQUIRED"/>
tx:method name="buyStock" isolation="DEFAULT" propagation="REQUIRED" rollback-for="BuyStockException"/>
tx:attributes>
tx:advice>
aop:config>
aop:pointcut expression="execution(* *..service.*.*(..))" id="point"/>
aop:advisor advice-ref="txAdvice" pointcut-ref="point"/>
aop:config>