spring事务浅析

 

事务分为编程式事务和声明式事务

声明式事务:


import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableRabbit//mq
@EnableScheduling//定时任务
@EnableTransactionManagement//使用注解开启事物管理
@SpringBootApplication        //same as @Configuration+@EnableAutoConfiguration+@ComponentScan
public class Application extends SpringBootServletInitializer {
	 protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
	        return application.sources(Application.class);
	    }

	 public static void main(String[] args) {
		 
		 //
		SpringApplication.run(Application.class, args);
	 }
}

事务使用:


    @Transactional(propagation = Propagation.NESTED)
    //使用注解使用事务,aop切片切入方法时候可以通过该注解进行事务管理
    @RequestMapping("buyAndPay")
    @ResponseBody
    public Msg buyAndPay(Integer[] car_id, Integer address_id, Double sumprice, HttpServletRequest request, Model model, double freight, String content, Integer integralMark, Integer inputIntegralCount, double deductionMoney) throws Exception{
        Msg msg = new Msg();
        User user=(User) request.getSession().getAttribute("user");
        if(user==null || user.getName()==null ||user.getName().equals("")){
            System.out.println(user.getName());
            msg.setResult(2);
            msg.setMessage("用户未注册");
            return msg;
            //return "redirect:/jyxtLoginController/jyxtRegister";
        }
        try {
            Object orderNo=	CreateOrderNoUtil.createOrderNo("1").get("orderNo");
            ScOrder order=new ScOrder();
            order.setAddress_id(address_id);
            order.setSumprice(sumprice);
            order.setUser_id(user.getId());
            order.setOrderNo(orderNo.toString());
            order.setFreight(freight);
            order.setType(1);
            order.setContent(content);
            //积分使用标志
            order.setIntegralMark(integralMark);
            if (integralMark == 0){
                //使用(输入)的积分数
                order.setInputIntegral(inputIntegralCount.toString());
                //使用积分抵扣的金额
                order.setDeductionMoney(deductionMoney);
            }else{
                //使用(输入)的积分数
                order.setInputIntegral("0");
                //使用积分抵扣的金额
                order.setDeductionMoney(0);
            }
            carService.insertOrderByorder(order);//sc_order
            jyxtUserOrderService.updateOrderInfo(2, 0, user.getId(), 1, order.getId(), 1);
            for (int i = 0; i < car_id.length; i++) {
                ScCar car=carService.getCarbyid(car_id[i]);//购物车结算
                ScProduct scProduct=new ScProduct();
                scProduct.setId(car.getProduct_id());
                scProduct=productService.getProductById(scProduct);
                ScOrderproduct orderproduct=new ScOrderproduct();
                ProductSpec productSpec=new ProductSpec();
                productSpec.setId(car.getSpec_id());
                productSpec=productService.getProductSpecBySpec(productSpec);
                orderproduct.setImgurl(scProduct.getImg());
                orderproduct.setNumber(car.getNumber());
                orderproduct.setOrder_id(order.getId());
                orderproduct.setProduct_id(scProduct.getId());
                orderproduct.setPrice(productSpec.getVipprice());
                orderproduct.setProductprice(productSpec.getPrice());
                orderproduct.setProduct_spec_id(productSpec.getId());
                orderService.insertOrderproductByproduct(orderproduct);
                //扣库存
                productSpec.setStock(car.getNumber());
                int result = productService.updateProductSpecBuyNumber(productSpec);
                if(result > 0) {

                }else {
                    //库存不足
                    logger.info("库存不足异常抛出,specID:{} , number :{}",productSpec.getId(),car.getNumber());
                    //throw new RuntimeException();
                    msg.setMessage(scProduct.getProduct()+"库存不足");
                    msg.setResult(0);//失败
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return msg;
                }
                carService.deleteProductcar(car);//清空购物车车

            }
            //新增定时任务
            SimpleDateFormat sdf_time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = new Date();
            JobDataMap jdb = new JobDataMap();
            jdb.put("orderId", order.getId());
            jdb.put("date", DataUtil.getDateAfterStringByMINUTEs(date, 15));//过期时间
            String quartzName = "quartzNameinfants";
            // 将订单放入定时
            quartzManager.addOrderJob(quartzName + order.getId(),
                    quartzName + "group" + order.getId(),
                    quartzName + "trigger" + order.getId(),
                    quartzName + "triggergroup" + order.getId(), InfantsScOrderJob.class,
                    CronDateUtils.getCron(DataUtil.getDateAfterStringByMINUTEs(date, 15)),
                    DataUtil.getDateAfterStringByMINUTEs(date, 15), jdb);
            msg.setMessage(order.getId()+"");
            msg.setResult(1);//成功

        }catch(Exception e) {
            e.printStackTrace();
            msg.setMessage("购买失败");
            msg.setResult(0);//失败
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return msg;
        //return "redirect:/WxPayController/payorder?id="+order.getId();
    }
事务的特性:

        一致性:事务执行前后一致性

        原子性:事务是一个整体不可分割

        持久性:事务结束,数据持久化到数据库

        隔离性:事务之间相互隔离,互不影响
事务的传递方法,一共七种

1>required(默认属性)
如果存在一个事务就支持当前事务如果没有就返回一个新的事务
2》MANDATORY(支持当前事务,如果没有事务,就抛出异常)
3》NEVER(以非事务方式运行,如果有事务就抛出异常)
4》NOT_SUPPORTED(以非事务方式运行,如果存在事务就把当前事务挂起)
5》REQUIES_NEW(新建事务,如果存在事务就挂起)
6》NEASTED(支持当前事务,与当前事务同时提交或回滚)
7》SUPPORTS(事务有就执行,无则不执行)
事务的隔离级别

read_uncommitted(读未提交)

read_committed(读已提交),oracle默认你支持

repeatable_read(重复读)  mysql默认支持

serializable(串行话,隔离级别最高)

注意:不同事务中调用同一个dao层方法,会造成死锁

编程式事务:使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。

1,添加tk

xmlns:tx="http://www.springframework.org/schema/tx"


2开启事务注解支持

<!-- 开启事务控制的注解支持 -->  
<tx:annotation-driven transaction-manager="transactionManager"/>

3、MyBatis自动参与到spring事务管理中,无需额外配置,只要org.mybatis.spring.SqlSessionFactoryBean引用的数据源与DataSourceTransactionManager引用的数据源一致即可。

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 
	<property name="dataSource" ref="dataSource" />  
	<property name="configLocation">  
		<value>classpath:mybatis-config.xml</value>  
	</property>  
</bean> 

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


事务配置文件
<tx:advice id="advice" transaction-manager="transactionManager">  
    <tx:attributes>  
        <tx:method name="update*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception"/>  
        <tx:method name="insert" propagation="REQUIRED" read-only="false"/>  
    </tx:attributes>  
</tx:advice>  
  
<aop:config>  
    <aop:pointcut id="testService" expression="execution (* com.nnngu.service.MyBatisService.*(..))"/>  
    <aop:advisor advice-ref="advice" pointcut-ref="testService"/>  
</aop:config>  


注意:
@Transactional 注解应该只被应用到 public 方法上,这是由 Spring AOP 的本质决定的。如果你在 protected、private 或者默认可见性的方法上使用 @Transactional 注解,这将被忽略,也不会抛出任何异常。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值