Hello,你们好,前面两篇文章给你们分享了Spring AOP,今天就趁热打铁,给你们分享一下,Spring中的事务,事务这个事,其实在国内一些小公司,通常都会忽略的,尤为是不少网站,设计不到钱的系统,不会在意这个东西,事务不回滚形成的结果无非就是脏数据,脏改等后果。由于做者之前待过的一个房产网站,根本就不在意这个事务,有问题就有问题了,反正用户也没充钱在网站上。呵呵。今天仍是和你们分享一下这个Spring的事务,由于这个东西算是Spring 内部使用AOP最好的一个体现,体现了AOP思想,OK,文章结构:html
看到Spring boot,不少人确定感受是被忽悠了,为何说讲Spring事务,这又来Spring boot搞事情。用过Spring boot的小伙伴其实都知道,这两个没什么大的区别,笔者这里使用Spring boot来演示,彻底是为何了简便。由于搭一个Spring传统的ssm三件套工程可能要花费5分钟,而搭建一个Spring boot的"ssm"工程,就是鼠标点一点的事。并且开启事务也是一个注解的事。因此,老铁们,对不住了,这一篇用Spring boot和你们演示Spring的事务,这里我给一个传送门,是传统项目的事务,你们能够参考下:java
废话说下,直接上Spring boot代码:mysql
@SpringBootApplication
@EnableTransactionManagement
public class TestTxApplication {
public static void main(String[] args) {
SpringApplication.run(TestTxApplication.class, args);
}
}
复制代码
@EnableTransactionManagement 表示开启事务!spring
@Component
public class PersonService {
@Autowired
private PersonMapper personMapper;
@Transactional
public void testTx(){
//该操做会成功
personMapper.update();
//该操做会报异常
personMapper.update2();
}
}
复制代码
这是一个Service,内部的personMapper是一个dao接口,持久化用的mybatissql
@Mapper
public interface PersonMapper {
//更改某条记录
@Update("update user_info set user_name='123' where user_id='1' ")
Long update();
//user_info2这个表不存在。会报异常
@Update("update user_info2 set user_name='123' where user_id='1' ")
Long update2();
}
复制代码
演示的效果应该是:数据库
具体我就不演示了 。你们能够看到,在Spring boot中开启事务就是一个注解的事 。具体的内部使用什么trancationManagement根本不用管,Spring boot内部会根据pom中引入的持久层框架自动注入。真是开发神器!数组
而后我说下底层原理:Spring事务其实就是Spring AOP,底层建立动态代理对象,在代码的开头结尾封装了开启事务和事务回滚操做。用过JDBC原生代码的更应该清楚了,都是显示在代理里commit和rollback的。而后一大堆try catch..mybatis
上面的代码虽然简单,也能应对大部分的场景,但仍是有一些问题的,好比,有些异常开发者知道,而且想人为的控制,"抛出某类异常,不要回滚".这样的问题。这就引出了,事务属性这个概念,事务属性一般由事务的传播行为,事务的隔离级别,事务的超时值和事务只读标志组成。 这些属性都是在使用@Transactional能够指定的,我给一张表格: app
而后把这些属性讲一讲:框架
事务的隔离界别:使用@Transactional的Isolation属性能够指定事务的隔离级别。但事务的隔离级别是由底层的数据库实现的,并非由Spring来实现。
通常的数据库默认提供的是READ_COMMITTED隔离级别,如sqlserver2000;Mysql默认提供的是REPEATABLE_READ;
好了,结论给你们说完了,而后解释一下上面提到的 脏读,不可重复读和幻象读的概念。
脏读:
不可重复读:在一个事务中先后两次读取的结果并不致,致使了不可重复读。
幻想读:
好了,事务的隔离级别就讲完了,通常仍是采用数据库默认的,像mysql的REPEATABLE_READ,可以避免脏读和不可重复读。
其余的传播行为省略,基本不用,通常的传播行为也是使用默认的:REQUIRED
Transactional的异常控制,默认是Check Exception不回滚,unCheck Exception回滚,rollbackFor 和noRollbackFor 配置也许不会含盖全部异常,对于遗漏的按照Check Exception 不回滚,unCheck Exception回滚.
使用@Transactional注解的noRollbackFor和rollbackFor属性能够改变默认的行为:
也可使用noRollbackForClassName、rollbackForClassName属性来指定一个异常类名的String数组来改变默认的行为。
好了,事务属性大体就这么多了,其余一些就是比较简单的了,看名字就知道啥意思,伸手就用的东西,而后再提一下,@Transactional只能被应用到public方法上, 对于其它非public的方法,若是标记了@Transactional也不会报错,但方法没有事务功能..
老实说,通常事务属性配置的比较少,通常都是直接@Transactional加上就完事了。不多配置一些属性。尤为是那个事务传播行为,在平常的业务里,不多有食物嵌套的状况,因此我就是点了一点,没有展开。通常使用默认就能够了。
好了,Spring的事务使用层面给你们算是分享完了,在Spring boot里想使用事务简单的有点可怕。因此我就采用Spring boot了。其实传统的SSM项目也很简单,无非就是在xml文件里配置下tranclationManagement..而后Spring 事务的底层是Spring AOP,把jdbc的事务代码嵌入了进去。Over,Have a good day!