详述Spring 框架事务 为什么 怎么做 @Transactional常用属性说明

Spring框架框架事务:

        为什么?

package club.shaoyu.coupon.service;

import java.util.UUID;

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

import club.shaoyu.book.dao.BookDao;
import club.shaoyu.coupon.dao.CouponDao;
import club.shaoyu.exception.UpdateException;
import club.shaoyu.money.dao.MoneyDao;
import club.shaoyu.vo.Coupon;

@Service
public class CouponService implements ICouponService {

	@Autowired
	private BookDao bookDao;
	@Autowired
	private MoneyDao moneyDao;
	@Autowired
	private CouponDao couponDao;
	
	@Override
	@Transactional
	public boolean insert(String bookId, String userId, int count) {
			if(bookDao.enough(bookId, count)) {
				try {
					bookDao.update(bookId, count);
				} catch (UpdateException e) {
					e.printStackTrace();
				}
			}
			float price =bookDao.getPrice(bookId);
			float totle=price*count;
			if(moneyDao.enough(userId, totle)) {
					Coupon coupon=new Coupon();
					coupon.setId(UUID.randomUUID().toString());
					coupon.setBookId(bookId);
					coupon.setUserId(userId);
					coupon.setTotle(totle);
					couponDao.insert(coupon);
					moneyDao.update(userId, totle);
			}
		return true;
	}
}

详述Spring 框架事务 为什么 怎么做 @Transactional常用属性说明_第1张图片

如图所示:我们在使用上述insert代码对数据库进行修改时,不难发现-->如果数据查询满足要求,但是钱包不够,此时仅仅可以将书籍修改,从而异常抛出-->为了解决上述问题-->我们使用Spring中的事务框架进行修改,达到的结果-->除非无异常抛出,其他的情况下均会使事务回滚,从而达到办公的要求

        @Transactional配置

一、是什么

@Transactional注解修饰的方法中会自动形成代理类并且形成上述Spring事务机制

二、怎么配置?




	
		
		
		
		
	
	
	
	
	
	
		
	
	
	

    在Spring中如下配置,与连接数据库配置多了transactionManager类和annotation-driven标签进行驱动

    相应的jar包:

    将此形成代理类的包引入:spring-aspects-4.3.10.RELEASE.jar

    同时Spring相关和数据连接池相关的以及log4j引入即可

三、怎么做?

    @Transactional(属性=数值)

       timeout属性和readOnly

           在timeout中的方法为描述,若是对应的方法在三秒钟不执行结束,那么指定不执行

          如果想测试,大可将Thread.sleep(20000)添加代码中

              输出的结果为:Transaction timed out: deadline was Thu Mar 19 18:26:35 CST 2020

         readOnly

          只读操作是不可以对数据进项修改,否则报错

            输出异常:Connection is read-only

       rollbackFor和rollbackForClassName

            前提:定对哪些异常回滚事务。默认情况下,如果在事务中抛出了运行时异常(继承自RuntimeException异常类),则回滚事务;如果没有抛出任何异常,或者抛出了检查时异常,则依然提交事务,这告诉我们要想回滚相应异常或者是不会滚异常,我们需要相应的属性进行控制

        rollbackFor=检查时异常类便可:、

     事物的传播级别:

          propagation:正常情况下-->假设一个事务中的中有方法去调用另外一个事务,那么另外这个事务如何创建?这便涉及到事物的传播机制问题        

               REQUIRED:默认值,如果有事务在运行,当前的方法就在这个事务内运行,否则,就启动一个新的事务,并在自己的事务内运行

               REQUIRES_NEW:当前方法必须启动新事务,并在它自己的事务内运行,如果有事务在运行,则把当前事务挂起,直到新的事务提交或者回滚才恢复执行

        此时若是在一个事务中调用一个事物多次,默认情况下其中一个子事务失败,则全部失败,若是第二种的话便会发生一个事物下的事务单独执行

               

     isolation:指定事务隔离级别,Spring定义了如下5种事务隔离级别:

        DEFAULT:默认值,表示使用底层数据库的默认隔离级别。对大部分数据库而言,通常为READ_COMMITTED。

        READ_UNCOMMITTED:表示一个事务可以读取另一个事务修改但还没有提交的数据。该级别可能出现脏读、不可重复读或幻读,因此很少使用该隔离级别。

        READ_COMMITTED:表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,但可能出现不可重复读或幻读,这也是大多数情况下的推荐值。

        REPEATABLE_READ:表示一个事务在整个过程中可以多次重复执行某个查询,且每次返回的记录都相同,除非数据被当前事务自生修改。即使在多次查询之间有新增的数据满足该查询,这些新增的记录也会被忽略。该级别可以防止脏读和不可重复读,但可能出现幻读。

        SERIALIZABLE:表示所有的事务依次逐个执行,事务之间互不干扰,该级别可以防止脏读、不可重复读和幻读,但是这将严重影响程序的性能,因此通常情况下也不会用到该级别。

        当多个事务同时发生,此时会发生多重不必要的行为,为了避免这些行为,我们采用上述方法将数据进行隔离,这些内容在前面的SQL中的事务隔离级别中也讲过

 

 

你可能感兴趣的:(spring)