Spring的事务管理

Spring的事务管理

什么是事务

事务:访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。

事务的特性(ACID)

原子性(Atomicity):一个事务是一个不可分割的整体,是一个操作序列,当数据修改时,这些操作序列要么全都执行,要么全都不执行。即,不允许事务部分地完成,避免了只执行这些操作的一部分而带来的错误。

一致性(Consistency):整个数据库的状态在事务执行前后必须保持一致性状态。比如银行转账,A账户转到B账户,不管转几次,A和B账户的总额不能变。

隔离性(Isolation):如果有多个并发事务,任意一个事务所做的操作不能被任何其它事务所作的修改干扰,事务与事务之间应该是透明的。

持久性(Durability):持久性是指事务的操作,一旦提交,对于数据库中数据状态的改变是永久性的,即使数据库发生故障也不能丢失已提交事务所完成的改变。

数据库事务的隔离级别

级别由低到高分为4种:级别越高,越能保证数据的越能保证数据的完整性统一性,但是对并发性能的影响也越大。

read uncommitted:读未提交.

顾名思义:其他事务可以读取到当前事务未提交的数据。-》会导致“脏读”,实际应用中很少应用此隔离级别。

read committed:读已提交

其他事务可以读取到当前事务已提交的数据。-》可能会出现“不可重复读”问题,该问题是一个事务执行过程中,另一事务提交并修改了当前事务正在读取的数据。向上提高隔离级别可解决。

repeatable read:可重复读

读取数据的事务将会禁止写事务,但允许读事务,写数据事务则禁止任何其他事务,解决了"不可重复读",但是会出现"幻读"问题

serializable:可串行化

提供严格的事务隔离。要求实施序列化执行,事务只能一个接一个地执行,不能并发执行,严重影响性能。

Spring中的事务

Spring抽象出一种default隔离级别,根据数据设置来变动。

read uncommitted(未提交读)
read committed(提交读、不可重复读)
repeatable read(可重复读)
serializable(可串行化)
defaultPlatformTransactionManager默认的隔离级别,使用的就是数据库默认的)

Spring的事务隔离级别比数据库的多出一个,这是因为Spring只提供统一事务管理接口,具体实现都是由各数据库自己实现(如MySQL,PostgreSql)。Spring会在事务开始时,根据当前环境中设置的隔离级别,调整数据库隔离级别,由此保持一致。

具体采用哪种隔离级别分三种情况

1.当Spring没有指定事务隔离级别,则会采用数据库默认的事务隔离级别;
2.当Spring指定了事务隔离级别,则会在代码里将事务隔离级别修改为指定值;
3.当数据库不支持这种隔离级别,效果则以数据库的为准(比如采用了MyISAM引擎);

在Spring中开启事务管理和声明式事务

Spring可以通过@Transactional来指定隔离级别和传播行为

@Transactional(isolation = Isolation.READ_UNCOMMITTED)

但是,如果不是有性能和需求问题,就最好不要改动隔离级别。事务处理弄不好是会锁表的,而锁表在大并发的情况下服务就崩了。

启事务管理声明式事务注解(xml方式),

<bean id="transactionManager" class="com.hikvision.cms.vms.common.frame.spring.transaction.BaseTransactionManager">
		<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>//增加对@Transactional的支持

在Spring Boot中开启事务管理:


@Configuration
@EnableTransactionManagement
public class TransactionConfiguration {
 
    @Bean
    @Qualifier("transactionManager")
    public PlatformTransactionManager txManager(@Qualifier("dataSource") DataSource dataSource){
        return new DataSourceTransactionManager(dataSource);
    }
}

开启后在需要使用事务的类或方法上标注@Transactional即可。

在查询用不用开启事务呢?

https://juejin.im/post/5ea66ca66fb9a03c4c5be52e

单条SQL语句

一般来说,开启事务是会影响数据库读写性能的,在单条sql语句查询时,没有必要开启事务,数据库默认的配置就能满足需求。

多条SQL查询语句

但如果你一次执行多条查询语句,例如统计查询,报表查询,在这种场景下,多条查询SQL必须保证整体的读一致性,否则,在前条SQL查询之后,后条SQL查询之前,数据被其他用户改变,就会造成数据的前后不一。
也仅有在这种情况下,要开启读事务

对于事务的使用要谨慎,判断是否一定要使用,如非必要,不要使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值