目录
3.1:PlatformTransactionManager (平台事务管理器)
3.3:TransactionDefinition 事务定义
6.1:PlatformTransactionManager实现
6.3:基于TransactionProxyFactoryBean (bean工厂代理)--需要显示的为每一个业务类配置,每多一个业务类就要进行添加
1:spring的7中事务传播行为
传播行为 | 含义 |
propagation_required(xml文件中为required) | 表示当前方法必须在一个具有事务的上下文中运行,如有客户端有事务在进行,那么被调用端将在该事务中运行,否则的话重新开启一个事务。(如果被调用端发生异常,那么调用端和被调用端事务都将回滚) |
propagation_supports(xml文件中为supports) | 表示当前方法不必需要具有一个事务上下文,但是如果有一个事务的话,它也可以在这个事务中运行,如果直接调用按照无事务方法执行 |
propagation_mandatory(xml文件中为mandatory) | 表示当前方法必须在一个事务中运行,如果没有事务,将抛出异常 |
propagation_nested(xml文件中为nested) | 嵌套事务: 外部回滚 内部也会回滚 内部回滚 不影响内部提交。这就是嵌套事务 嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚。 |
propagation_never(xml文件中为never) | 表示当方法务不应该在一个事务中运行,如果存在一个事务,则抛出异常 |
propagation_requires_new(xml文件中为requires_new) | 在上级方法是事务方法情况下,多个子方法使用该注解, 子方法之间事务互不干扰,会创建新的事务 比如说子方法1事务回滚会导致主方法事务回滚,但是其他的子方法事务可以提交 |
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.1:PlatformTransactionManager (平台事务管理器)
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.2:TransactionStatus 事务状态
在上面 PlatformTransactionManager 接口中,有如下方法:
这个方法返回的是 TransactionStatus对象,然后程序根据返回的对象来获取事务状态,然后进行相应的操作。
而 TransactionStatus 这个接口的内容如下:
这个接口描述的是一些处理事务提供简单的控制事务执行和查询事务状态的方法,在回滚或提交的时候需要应用对应的事务状态
3.3:TransactionDefinition 事务定义
上面讲到的事务管理器接口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;
}
// set get方法省略
}
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&useUnicode=true&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.1:PlatformTransactionManager实现
配置文件
<?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 {
TransactionStatus status=transactionManager.getTransaction(transactionDefinition);
//插入一条订单数据并且根据订单数据的下单数在商品表库存相对减少
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.2:TransactionTemplate实现
配置文件:
<?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:声明式事务实现
编程事务不利于代码扩展,每次都需要手动开启事务,和代码耦合在一起,没有用到Spring的Aop思想
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代码:
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,'正常');