Spring_第六章【Spring的事务代码实现】

1:spring的7中事务传播行为

 

传播行为

含义

propagation_required(xml文件中为required)

表示当前方法必须在一个具有事务的上下文中运行,如有客户端有事务在进行,那么被调用端将在该事务中运行,否则的话重新开启一个事务。(如果被调用端发生异常,那么调用端和被调用端事务都将回滚)

propagation_supports(xml文件中为supports)

表示当前方法不必需要具有一个事务上下文,但是如果有一个事务的话,它也可以在这个事务中运行

propagation_mandatory(xml文件中为mandatory)

表示当前方法必须在一个事务中运行,如果没有事务,将抛出异常

propagation_nested(xml文件中为nested)

表示如果当前方法正有一个事务在运行中,则该方法应该运行在一个嵌套事务中,被嵌套的事务可以独立于被封装的事务中进行提交或者回滚。如果封装事务存在,并且外层事务抛出异常回滚,那么内层事务必须回滚,反之,内层事务并不影响外层事务。如果封装事务不存在,则同propagation_required的一样

propagation_never(xml文件中为never)

表示当方法务不应该在一个事务中运行,如果存在一个事务,则抛出异常

propagation_requires_new(xml文件中为requires_new)

表示当前方法必须运行在它自己的事务中。一个新的事务将启动,而且如果有一个现有的事务在运行的话,则这个方法将在运行期被挂起,直到新的事务提交或者回滚才恢复执行。

propagation_not_supported(xml文件中为not_supported)

表示该方法不应该在一个事务中运行。如果有一个事务正在运行,他将在运行期被挂起,直到这个事务提交或者回滚才恢复执行

 

2:Spring对应数据库中的事务隔离级别

 

隔离级别

含义

isolation_default

使用数据库默认的事务隔离级别

isolation_read_uncommitted

允许读取尚未提交的修改,可能导致脏读、幻读和不可重复读

isolation_read_committed 

允许从已经提交的事务读取,可防止脏读、但幻读,不可重复读仍然有可能发生

isolation_repeatable_read

对相同字段的多次读取的结果是一致的,除非数据被当前事务自生修改。可防止脏读和不可重复读,但幻读仍有可能发生

isolation_serializable 

完全服从acid隔离原则,确保不发生脏读、不可重复读、和幻读,但执行效率最低。

3:Spring事务接口简介


3.1PlatformTransactionManager  (平台事务管理器)

 Spring事务管理器的接口是org.springframework.transaction.PlatfromTransactionManager,如上图所示,Spring并不直接管理事务,

通过这个接口,Spring为各个平台如JDBC、Hibernate等都提供了对应的事务管理器,也就是将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现。

 我们进入到 PlatformTransactionManager 接口,查看源码:

  

①、TransactionStatus getTransaction(TransactionDefinition definition) ,事务管理器 通过TransactionDefinition,获得“事务状态”,从而管理事务。

  ②、void commit(TransactionStatus status)  根据状态提交

  ③、void rollback(TransactionStatus status) 根据状态回滚

  也就是说Spring事务管理的为不同的事务API提供一致的编程模型,具体的事务管理机制由对应各个平台去实现。 

比如下面我们导入实现事务管理的两种平台:JDBC和Hibernate

  

然后我们再次查看PlatformTransactionManager接口,会发现它多了几个实现类,如下:

  

 

3.2TransactionStatus 事务状态

  在上面 PlatformTransactionManager 接口中,有如下方法:

   

  这个方法返回的是 TransactionStatus对象,然后程序根据返回的对象来获取事务状态,然后进行相应的操作。

  而 TransactionStatus 这个接口的内容如下:

  

  这个接口描述的是一些处理事务提供简单的控制事务执行和查询事务状态的方法,在回滚或提交的时候需要应用对应的事务状态

3.3TransactionDefinition 事务定义

 上面讲到的事务管理器接口PlatformTransactionManager通过getTransaction(TransactionDefinition definition)方法来得到事务,这个方法里面的参数是TransactionDefinition类,这个类就定义了一些基本的事务属性。 

那么什么是事务属性呢?事务属性可以理解成事务的一些基本配置,描述了事务策略如何应用到方法上。事务属性包含了5个方面,如图所示:

  

TransactionDefinition 接口方法如下:

  

 

 

4:Spring实现事务主要有两种方式

 编程式事务处理:所谓编程式事务指的是通过编码方式实现事务,允许用户在代码中精确定义事务的边界。即类似于JDBC编程实现事务管理。管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。

 声明式事务处理:管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。

  简单地说,编程式事务侵入到了业务代码里面,但是提供了更加详细的事务管理;而声明式事务由于基于AOP,所以既能起到事务管理的作用,又可以不影响业务代码的具体实现。

5:公共代码

实体两个:分别是订单和商品

package com.thit.entity;

import java.util.Date;
//订单表
public class Order {
    private String id;//订单id
    private String productsId;//商品id
    private int number;//购买数量
    private double price;//价格
    private Date createTime;//下单时间
    private Date sendTime;//发单时间
    private Date confirmTime;//确认收货时间
    private String consignee;//收货人
    private String consigneePhone;//收货人电话
    private String consigneeAddress;//收货人地址
    private String status;//状态

    public Order() {
    }

    public Order(String id, String productsId, int number, double price, String consignee,                 String consigneePhone, String consigneeAddress) {
        this.id = id;
        this.productsId = productsId;
        this.number = number;
        this.price = price;
        this.consignee = consignee;
        this.consigneePhone = consigneePhone;
        this.consigneeAddress = consigneeAddress;
    }

    public String getProductsId() {
        return productsId;
    }

    public void setProductsId(String productsId) {
        this.productsId = productsId;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getSendTime() {
        return sendTime;
    }

    public void setSendTime(Date sendTime) {
        this.sendTime = sendTime;
    }

    public Date getConfirmTime() {
        return confirmTime;
    }

    public void setConfirmTime(Date confirmTime) {
        this.confirmTime = confirmTime;
    }

    public String getConsignee() {
        return consignee;
    }

    public void setConsignee(String consignee) {
        this.consignee = consignee;
    }

    public String getConsigneePhone() {
        return consigneePhone;
    }

    public void setConsigneePhone(String consigneePhone) {
        this.consigneePhone = consigneePhone;
    }

    public String getConsigneeAddress() {
        return consigneeAddress;
    }

    public void setConsigneeAddress(String consigneeAddress) {
        this.consigneeAddress = consigneeAddress;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    
}

dao和实现类两个

package com.thit.dao;

import java.util.List;

import com.thit.entity.Order;

public interface OrderDao {
	void insert(Order order);
	void update(Order order);
	void delete(String id);
	Order select(String id);
	List<Order> select();
}


----实现类----
package com.thit.daoimpl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import com.thit.dao.OrderDao;
import com.thit.entity.Order;

@Repository
public class OrderDaoImpl implements OrderDao {
	@Autowired
	private JdbcTemplate jdbcTemplate;

	public void insert(Order order) {
		// TODO Auto-generated method stub
		String sql = "insert into orders values(?,?,?,?,?,?,?,?,?,?,?)";
		jdbcTemplate.update(sql, order.getId(), order.getProductsId(), order.getNumber(), order.getPrice(),
				order.getCreateTime(), order.getSendTime(), order.getConfirmTime(), order.getConsignee(),
				order.getConsigneePhone(), order.getConsigneeAddress(), order.getStatus());

	}

	public void update(Order order) {
		// TODO Auto-generated method stub
		String sql = "update orders set create_time=?,send_time=?,confirm_time=?,consignee=?,consignee_phone=?,consignee_address=?,status=? where id=?";
		jdbcTemplate.update(sql, order.getProductsId(), order.getNumber(), order.getPrice(), order.getCreateTime(),
				order.getSendTime(), order.getConfirmTime(), order.getConsignee(), order.getConsigneePhone(),
				order.getConsigneeAddress(), order.getStatus(), order.getId());

	}

	public void delete(String id) {
		// TODO Auto-generated method stub
		String sql = "delete from orders where id=?";
		jdbcTemplate.update(sql, id);
	}

	public Order select(String id) {
		// TODO Auto-generated method stub
		 String sql = "select form orders where id=?";
		return jdbcTemplate.queryForObject(sql, new OrderRowMapper(), id);
	}

	public List<Order> select() {
		// TODO Auto-generated method stub
		String sql = "select * from orders";
		return jdbcTemplate.query(sql, new OrderRowMapper());
	}

	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	private class OrderRowMapper implements RowMapper<Order> {

		public Order mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			// TODO Auto-generated method stub
			Order order = new Order();
			order.setId(resultSet.getString("id"));
			order.setProductsId(resultSet.getString("products_id"));
			order.setNumber(resultSet.getInt("number"));
			order.setPrice(resultSet.getDouble("price"));
			order.setCreateTime(resultSet.getTimestamp("create_time"));
			order.setSendTime(resultSet.getTimestamp("send_time"));
			order.setConfirmTime(resultSet.getTimestamp("confirm_time"));
			order.setConsignee(resultSet.getString("consignee"));
			order.setConsigneePhone(resultSet.getString("consignee_phone"));
			order.setConsigneeAddress(resultSet.getString("consignee_address"));
			order.setStatus(resultSet.getString("status"));
			return order;
		}

	}
}
package com.thit.dao;

import java.util.List;

import com.thit.entity.Product;

public interface ProductDao {
	void insert(Product product);
	void update(Product product);
	void delete(String id);
	Product select(String  id);
	List<Product> select();

}


-----实现类----
package com.thit.daoimpl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import com.thit.dao.ProductDao;
import com.thit.entity.Product;
@Repository
public class ProductDaoImpl implements ProductDao {
	//通过set方法自动注入
	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	public void insert(Product product) {
	     String sql = "insert into products values(?,?,?,?,?)";
	     jdbcTemplate.update(sql,product.getId(),product.getTitle(),product.getPrice(),product.getStock(),product.getStatus());
	    
	}

	public void update(Product product) {
	      String sql = "update products set title=?,price=?,stock=?,status=? where id=?";
	      jdbcTemplate.update(sql,product.getTitle(),product.getPrice(),product.getStock(),product.getStatus(),product.getId());
	   
	}

	public void delete(String  id) {
		// TODO Auto-generated method stub
		   String sql = "delete form products where id=?";
	       jdbcTemplate.update(sql);
	}

	public Product select(String  id) {
		  String sql = "select * from products where id=?";
		  Product p=jdbcTemplate.queryForObject(sql, new RowMapper<Product>() {
		  public Product mapRow(ResultSet resultSet, int rowNum) throws SQLException {
				// TODO Auto-generated method stub
				Product product=new Product();
				product.setId(resultSet.getString("id"));
	            product.setTitle(resultSet.getString("title"));
	            product.setPrice(resultSet.getDouble("price"));
	            product.setStock(resultSet.getInt("stock"));
	            product.setStatus(resultSet.getString("status"));
				return product;
			}
		}, id);
		return p;
	}

	
	public List<Product> select() {
		// TODO Auto-generated method stub
		 String sql = "select * from products";
		 List<Product> list= jdbcTemplate.query(sql,new RowMapper<Product>() {
			public Product mapRow(ResultSet resultSet, int rowNum) throws SQLException {
				Product product=new Product();
				product.setId(resultSet.getString("id"));
	            product.setTitle(resultSet.getString("title"));
	            product.setPrice(resultSet.getDouble("price"));
	            product.setStock(resultSet.getInt("stock"));
	            product.setStatus(resultSet.getString("status"));
				return product;
			}
		});
		return list;
	}
	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

}

service

package com.thit.service;

import com.thit.entity.Order;

public interface OrderService {
	void addOrder(Order order);
}

公共配置文件:spring_dao.xml

<context:component-scan base-package="com.thit.daoimpl"></context:component-scan>
	<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
		<property name="url" value="jdbc:mysql://localhost:3306/xxx?serverTimezone=GMT&amp;useUnicode=true&amp;characterEncoding=UTF-8"></property>
		<property name="username" value="root"></property>
		<property name="password" value="123456"></property>
	</bean>


	<bean id="Template" class="org.springframework.jdbc.core.JdbcTemplate" >
		<property name="dataSource" ref="datasource"></property>
	</bean>

根据不同的serviceImp来方案验证不同的结果

 

6:编程式事务实现

6.1PlatformTransactionManager实现

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p"
	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">
<import resource="spring_dao.xml"/>
	<!-- 基于底层API的spring事务管理
		private PlatformTransactionManager transactionManager;
		TransactionDefinition transactionDefinition;
		TransactionStatus  status;
	 -->
 	<context:component-scan base-package="com.thit"></context:component-scan>

	<bean id="tsManager"  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="datasource" />
	</bean>
		
	<bean id="tsDefinition"  class="org.springframework.transaction.support.DefaultTransactionDefinition">
		<property name="propagationBehaviorName" value="PROPAGATION_REQUIRED" />
	</bean>

</beans>

代码实现类

package com.thit.serviceImpl;

import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

import com.thit.dao.OrderDao;
import com.thit.dao.ProductDao;
import com.thit.entity.Order;
import com.thit.entity.Product;
import com.thit.service.OrderService;
@Service(value="orderServiceimpl111")
public class OrderServiceImpl implements OrderService {
	@Autowired
	private OrderDao orderDao;
	@Autowired
	private ProductDao productDao;
	@Autowired
	private PlatformTransactionManager transactionManager;
	@Autowired
	private TransactionDefinition transactionDefinition;
	
	//private HibernateTransactionManager hibernateTransactionManager;
	public void addOrder(Order order) {
		// TODO Auto-generated method stub
		//订单表
		order.setCreateTime(new Date());
	    order.setStatus("待付款");
	    TransactionStatus  status=null;
	    //开启事务
	    try {
	    	
	    	//插入一条订单数据并且根据订单数据的下单数在商品表库存相对减少
	 		orderDao.insert(order);
	 		Product p=productDao.select(order.getProductsId());
	 		p.setStock(p.getStock()-order.getNumber());
	 		productDao.update(p);
	 		//提交事务
	 		transactionManager.commit(status);
		} catch (Exception e) {
			// TODO: handle exception
			transactionManager.rollback(status);
			e.printStackTrace();
		}
	   
	}
}

6.2TransactionTemplate实现

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p"
	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">
<import resource="spring_dao.xml"/>
<!-- spring 编程式事务基于transactionTemplate
 -->
	<context:component-scan base-package="com.thit"></context:component-scan>

		<bean id="tsManager"  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
			<property name="dataSource" ref="datasource" />
		</bean>
		
	<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="tsManager"/>
    </bean>
</beans>

代码实现:

package com.thit.serviceImpl;

import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import com.thit.dao.OrderDao;
import com.thit.dao.ProductDao;
import com.thit.entity.Order;
import com.thit.entity.Product;
import com.thit.service.OrderService;
@Service(value="orderServiceimpl2")
public class OrderServiceImpl2 implements OrderService {
	@Autowired
	private OrderDao orderDao;
	@Autowired
	private ProductDao productDao;
	@Autowired
	private TransactionTemplate template;
	
	public void addOrder(final Order order) {
		// TODO Auto-generated method stub
		//订单表
		System.out.println("进入");
		order.setCreateTime(new Date());
	    order.setStatus("待付款测试2");
	    template.execute(new TransactionCallback<Object>() {

			public Object doInTransaction(TransactionStatus status) {
				// TODO Auto-generated method stub
				 //开启事务
			    try {
			 		orderDao.insert(order);
			 		//商品
			 		Product p=productDao.select(order.getProductsId());
			 		p.setStock(p.getStock()-order.getNumber());
			 		productDao.update(p);
			 		
					
				} catch (Exception e) {
					// TODO: handle exception
					//回滚
					status.setRollbackOnly();
					e.printStackTrace();
				}
				return null;
			}
		});
	    
	   
	   
	}

}

6.3基于TransactionProxyFactoryBean (bean工厂代理)--需要显示的为每一个业务类配置,每多一个业务类就要进行添加

	<import resource="spring_dao.xml" />
	<!-- spring bean工厂代理 -->

	<bean id="tsManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="datasource" />
	</bean>

	<bean id="OrderServiceImpl3"  class="com.thit.serviceImpl.OrderServiceImpl3"></bean>

	 <bean id="orderService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager" ref="tsManager"/>
        <property name="transactionAttributes">
            <props>
                <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="search*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
        <property name="target" ref="OrderServiceImpl3"/>
    </bean>

Java代码:

package com.thit.serviceImpl;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import com.thit.dao.OrderDao;
import com.thit.dao.ProductDao;
import com.thit.entity.Order;
import com.thit.entity.Product;
import com.thit.service.OrderService;


public class OrderServiceImpl3 implements OrderService {
	@Autowired
	private OrderDao orderDao;
	@Autowired
	private ProductDao productDao;

	public void addOrder( Order order) {
		// TODO Auto-generated method stub
		// 订单表
		System.out.println("进入");
		order.setCreateTime(new Date());
		order.setStatus("待付款测试2");
		List<Order> list=orderDao.select();
		System.out.println(list.size());
		orderDao.insert(order);
		// 商品
		Product p = productDao.select(order.getProductsId());
		p.setStock(p.getStock() - order.getNumber());
		productDao.update(p);

	}

}

7:声明式事务实现

7.1基于配置文件

配置文件如下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p"
	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">
	<import resource="spring_dao.xml" />
	<!-- spring 声明式事务 -->
	<bean id="OrderServiceImpl5"  class="com.thit.serviceImpl.OrderServiceImpl3"></bean>
		<!-- 1 事务管理器 -->								
	<bean id="tsManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="datasource" />
	</bean>

    <!-- 2 事务详情(事务通知)  , 在aop筛选基础上,比如对ABC三个确定使用什么样的事务。例            如:AC读写、B只读 等
        <tx:attributes> 用于配置事务详情(属性属性)
            <tx:method name=""/> 详情具体配置
                propagation 传播行为 , REQUIRED:必须;
            REQUIRES_NEW:必须是新的
                isolation 隔离级别
    -->
	   <tx:advice id="txid" transaction-manager="tsManager">
		   <tx:attributes>
		   			<tx:method name="insert*" propagation="REQUIRED" isolation="DEFAULT"/>
		   			<tx:method name="delete*" propagation="REQUIRED" isolation="REPEATABLE_READ"/>
		   			<tx:method name="select*" propagation="REQUIRED"/>
		   			<tx:method name="update*" propagation="REQUIRED"/>
		   			<tx:method name="*" propagation="REQUIRED"/>
		   </tx:attributes>
	   </tx:advice>
<!-- 将管理器交予spring
        * transaction-manager 配置事务管理器
        * proxy-target-class
            false:jdk实现动态代理
            true : 底层强制使用cglib 代理
    -->
<!-- 3 AOP编程,利用切入点表达式从目标类方法中 确定增强的连接器,从而获得切入点 -->
	<aop:config proxy-target-class="false">
		<aop:pointcut id="pointcutid" expression="execution(* com.thit.serviceImpl.*.*(..))" />
		<!-- 关联切入点和通知 -->
		<aop:advisor advice-ref="txid" pointcut-ref="pointcutid"/>
	</aop:config>
</beans>

Java代码:

package com.thit.serviceImpl;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import com.thit.dao.OrderDao;
import com.thit.dao.ProductDao;
import com.thit.entity.Order;
import com.thit.entity.Product;
import com.thit.service.OrderService;


public class OrderServiceImpl3 implements OrderService {
	@Autowired
	private OrderDao orderDao;
	@Autowired
	private ProductDao productDao;
	//声明式事务代码简洁  第一种当时基于拦截器
	public void addOrder( Order order) {
		// TODO Auto-generated method stub
		// 订单表
		System.out.println("进入");
		order.setCreateTime(new Date());
		order.setStatus("待付款测试2");
		List<Order> list=orderDao.select();
		System.out.println(list.size());
		orderDao.insert(order);
		// 商品
		Product p = productDao.select(order.getProductsId());
		p.setStock(p.getStock() - order.getNumber());
		productDao.update(p);

	}

}

7.2基于注解实现声明式事务

配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p"
	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">
	<import resource="spring_dao.xml" />
	<context:component-scan base-package="com.thit.servicImpl"></context:component-scan>
	<!-- spring 基于注解的tx -->				
	<bean id="tsManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="datasource" />
	</bean>
	<!-- 事务驱动 -->
	<tx:annotation-driven transaction-manager="tsManager" proxy-target-class="true"/>
</beans>

代码只需要添加

package com.thit.servicImpl;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.thit.dao.OrderDao;
import com.thit.dao.ProductDao;
import com.thit.entity.Order;
import com.thit.entity.Product;
import com.thit.service.OrderService;

@Service(value="OrderServiceImpl6")
public class OrderServiceImpl6 implements OrderService {
	@Autowired
	private OrderDao orderDao;
	@Autowired
	private ProductDao productDao;
	//设置事务传播性和隔离级别
	@Transactional(propagation=Propagation.REQUIRED,readOnly=false,isolation=Isolation.REPEATABLE_READ)
	public void addOrder( Order order) {
		// TODO Auto-generated method stub
		// 订单表
		System.out.println("进入");
		order.setCreateTime(new Date());
		order.setStatus("待付款测试2");
		List<Order> list=orderDao.select();
		System.out.println(list.size());
		orderDao.insert(order);
		// 商品
		Product p = productDao.select(order.getProductsId());
		p.setStock(p.getStock() - order.getNumber());
		productDao.update(p);

	}

}

测试代码如下:

package com.thit.test;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.thit.entity.Order;
import com.thit.servicImpl.OrderServiceImpl6;
import com.thit.service.OrderService;
import com.thit.serviceImpl.OrderServiceImpl;
import com.thit.serviceImpl.OrderServiceImpl2;
import com.thit.serviceImpl.OrderServiceImpl3;

public class test1 {
	public static void main(String[] args) {
		test1 t = new test1();
		t.testAddOrder6();
	}

	// 基于底层API
	public void testAddOrder() {
		System.out.println("开始1132");
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring_service1.xml");

		Order order = new Order("100023", "100002", 2, 1799, "", "", "测试1");

		OrderServiceImpl orderServiceImpl = (OrderServiceImpl) applicationContext.getBean("orderServiceimpl111");
		orderServiceImpl.addOrder(order);
	}

	// 基于transactiontemplate
	public void testAddOrder1() {
		System.out.println("开始");
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring_service2.xml");

		Order order = new Order("100025", "100002", 2, 1799, "", "", "");

		OrderServiceImpl2 orderServiceImpl = (OrderServiceImpl2) applicationContext.getBean("orderServiceimpl2");
		orderServiceImpl.addOrder(order);
	}

	// 申明式事务,基于配置文件
	public void testAddOrder3() {
		System.out.println("开始3");
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring_service3.xml");

		Order order = new Order("100035", "100002", 2, 1799, "", "", "申请式事务testAddOrder3()");

		OrderServiceImpl3 orderServiceImpl = (OrderServiceImpl3) applicationContext.getBean("OrderServiceImpl3");
		orderServiceImpl.addOrder(order);
	}

	// 申明式事务,基于配置文件
	public void testAddOrder4() {
		System.out.println("开始4");
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring_service4.xml");

		Order order = new Order("100034", "100002", 2, 1799, "", "", "申请式事务testAddOrder4");

		OrderServiceImpl3 orderServiceImpl = (OrderServiceImpl3) applicationContext.getBean("OrderServiceImpl3");
		orderServiceImpl.addOrder(order);
	}
	
	// 申明式事务,基于配置文件
	public void testAddOrder5() {
		System.out.println("开始5");
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring_service5.xml");

		Order order = new Order("100041", "100002", 2, 1799, "", "", "申请式事务testAddOrder5() ");

		OrderServiceImpl3 orderServiceImpl = (OrderServiceImpl3) applicationContext.getBean("OrderServiceImpl5");
		orderServiceImpl.addOrder(order);
	}
	
	
	// 申明式事务,基于配置文件
		public void testAddOrder6() {
			System.out.println("开始6");
			ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring_service6.xml");

			Order order = new Order("100043", "100002", 2, 1799, "", "", "申请式事务testAddOrder5() ");

			OrderService orderServiceImpl = (OrderService) applicationContext.getBean("OrderServiceImpl6");
			orderServiceImpl.addOrder(order);
		}
}

=========================================================================================================

项目目录结构

附录建表sql:

//订单表
create table orders
(
   id                   char(6) not null COMMENT '编号',
   products_id          char(6) not null COMMENT '商品编号',
   number               int COMMENT '数量',
   price                double COMMENT '价格',
   create_time          datetime COMMENT '下单时间',
   send_time            datetime COMMENT '发货时间',
   confirm_time         datetime COMMENT '确认收货时间',
   consignee            varchar(20) COMMENT '收货人',
   consignee_phone      char(11) COMMENT '收货人电话',
   consignee_address    varchar(100) COMMENT '收货人地址',
   status               varchar(10) COMMENT '状态',
   primary key (id)
);

//商品表
create table products
(
   id                   char(6) not null COMMENT '商品id',
   title                varchar(20) COMMENT '商品名称',
   price                double COMMENT '价格',
   stock                int COMMENT '库存数',
   status               varchar(10) COMMENT '状态',
   primary key (id)
);


insert into products values('100001','苹果',2,100,'正常');
insert into products values('100002','香蕉',5,100,'正常');
insert into products values('100003','橘子',5,100,'正常');

参考地址:https://www.cnblogs.com/ysocean/p/7617620.html#_label3

猜你喜欢

转载自blog.csdn.net/huyiju/article/details/82253854